I adding an Event to Asset_Tracker_V2. I have created bms_module_evnet.h and bms_event.c files in events folder and bms_module.c. I have defined inclusion of these files in corresponding CMakeLists.TXT files. I added the BMS related states, enumerated parameters etc in app_module_event.c and app_module_event.h file also. I have added code of bms part in app_event_handler function of main.c.
I wrote code to :
1. sent BMS Events in response to (IS_EVENT(msg, app, APP_EVT_START)), (IS_EVENT(msg, app, APP_EVT_CONFIG_GET)) , (IS_EVENT(msg, app, APP_EVT_DATA_GET)) Events generated by app_module. When, I run the program and observe the various Events. The APP_EVT_START event by event_manager is generated at initial stage. In response to it various other modules like UI, DATA, CLOUD, MODEM etc submit their events, but BMS event is not seen, while I have written the code to respond to APP_EVT_START event in on_state_init() function.
What may be the reason ? 1. BMS_THREAD not initialized 2. module_get_next_msg(&self, &msg); function not getting any messages 3. In the on_state_init() function, Event is not detected or Event is not submitted. So, please explain me how to add an event.
The major files, where I have added BMS code are in attachment. At last, the log file created by LTE_LINK_MONITOR is attached.
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <app_event_manager.h>
#if defined(CONFIG_NRF_MODEM_LIB)
#include <modem/nrf_modem_lib.h>
#endif /* CONFIG_NRF_MODEM_LIB */
#include <sys/reboot.h>
#if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS)
#include <net/nrf_cloud_agps.h>
#endif
/* Module name is used by the Application Event Manager macros in this file */
#define MODULE main
#include <caf/events/module_state_event.h>
#include "modules_common.h"
#include "events/app_module_event.h"
#include "events/cloud_module_event.h"
#include "events/data_module_event.h"
#include "events/sensor_module_event.h"
#include "events/ui_module_event.h"
#include "events/util_module_event.h"
#include "events/modem_module_event.h"
#include "events/led_state_event.h"
#include "events/bms_module_event.h"
#include <logging/log.h>
#include <logging/log_ctrl.h>
LOG_MODULE_REGISTER(MODULE, CONFIG_APPLICATION_MODULE_LOG_LEVEL);
/* Message structure. Events from other modules are converted to messages
* in the Application Event Manager handler, and then queued up in the message queue
* for processing in the main thread.
*/
struct app_msg_data {
union {
struct cloud_module_event cloud;
struct ui_module_event ui;
struct sensor_module_event sensor;
struct data_module_event data;
struct util_module_event util;
struct modem_module_event modem;
struct app_module_event app;
struct bms_module_event bms;
} module;
};
/* Application module super states. */
static enum state_type {
STATE_INIT,
STATE_RUNNING,
STATE_SHUTDOWN
} state;
/* Application sub states. The application can be in either active or passive
* mode.
*
* Active mode: Sensor data and GNSS position is acquired at a configured
* interval and sent to cloud.
*
* Passive mode: Sensor data and GNSS position is acquired when movement is
* detected, or after the configured movement timeout occurs.
*/
static enum sub_state_type {
SUB_STATE_ACTIVE_MODE,
SUB_STATE_PASSIVE_MODE,
} sub_state;
/* Internal copy of the device configuration. */
static struct cloud_data_cfg app_cfg;
/* Timer callback used to signal when timeout has occurred both in active
* and passive mode.
*/
static void data_sample_timer_handler(struct k_timer *timer);
/* Timer callback used to signal when the application is expecting movement to trigger the next
* sample request.
*/
static void waiting_for_movement_handler(struct k_timer *timer);
/* Application module message queue. */
#define APP_QUEUE_ENTRY_COUNT 10
#define APP_QUEUE_BYTE_ALIGNMENT 4
K_MSGQ_DEFINE(msgq_app, sizeof(struct app_msg_data), APP_QUEUE_ENTRY_COUNT,
APP_QUEUE_BYTE_ALIGNMENT);
/* Data sample timer used in active mode. */
K_TIMER_DEFINE(data_sample_timer, data_sample_timer_handler, NULL);
/* Movement timer used to detect movement timeouts in passive mode. */
K_TIMER_DEFINE(movement_timeout_timer, data_sample_timer_handler, NULL);
/* Movement resolution timer decides the period after movement that consecutive
* movements are ignored and do not cause data collection. This is used to
* lower power consumption by limiting how often GNSS search is performed and
* data is sent on air.
*/
K_TIMER_DEFINE(movement_resolution_timer, waiting_for_movement_handler, NULL);
/* Module data structure to hold information of the application module, which
* opens up for using convenience functions available for modules.
*/
static struct module_data self = {
.name = "app",
.msg_q = &msgq_app,
.supports_shutdown = true,
};
/* Convenience functions used in internal state handling. */
static char *state2str(enum state_type new_state)
{
switch (new_state) {
case STATE_INIT:
return "STATE_INIT";
case STATE_RUNNING:
return "STATE_RUNNING";
case STATE_SHUTDOWN:
return "STATE_SHUTDOWN";
default:
return "Unknown";
}
}
static char *sub_state2str(enum sub_state_type new_state)
{
switch (new_state) {
case SUB_STATE_ACTIVE_MODE:
return "SUB_STATE_ACTIVE_MODE";
case SUB_STATE_PASSIVE_MODE:
return "SUB_STATE_PASSIVE_MODE";
default:
return "Unknown";
}
}
static void state_set(enum state_type new_state)
{
if (new_state == state) {
LOG_DBG("State: %s", state2str(state));
return;
}
LOG_DBG("State transition %s --> %s",
state2str(state),
state2str(new_state));
state = new_state;
}
static void sub_state_set(enum sub_state_type new_state)
{
if (new_state == sub_state) {
LOG_DBG("Sub state: %s", sub_state2str(sub_state));
return;
}
LOG_DBG("Sub state transition %s --> %s",
sub_state2str(sub_state),
sub_state2str(new_state));
sub_state = new_state;
}
/* Check the return code from nRF modem library initializaton to ensure that
* the modem is rebooted if a modem firmware update is ready to be applied or
* an error condition occurred during firmware update or library initialization.
*/
static void handle_nrf_modem_lib_init_ret(void)
{
#if defined(CONFIG_NRF_MODEM_LIB)
int ret = nrf_modem_lib_get_init_ret();
/* Handle return values relating to modem firmware update */
switch (ret) {
case 0:
/* Initialization successful, no action required. */
return;
case MODEM_DFU_RESULT_OK:
LOG_INF("MODEM UPDATE OK. Will run new firmware after reboot");
break;
case MODEM_DFU_RESULT_UUID_ERROR:
case MODEM_DFU_RESULT_AUTH_ERROR:
LOG_ERR("MODEM UPDATE ERROR %d. Will run old firmware", ret);
break;
case MODEM_DFU_RESULT_HARDWARE_ERROR:
case MODEM_DFU_RESULT_INTERNAL_ERROR:
LOG_ERR("MODEM UPDATE FATAL ERROR %d. Modem failure", ret);
break;
default:
/* All non-zero return codes other than DFU result codes are
* considered irrecoverable and a reboot is needed.
*/
LOG_ERR("nRF modem lib initialization failed, error: %d", ret);
break;
}
LOG_WRN("Rebooting...");
LOG_PANIC();
sys_reboot(SYS_REBOOT_COLD);
#endif /* CONFIG_NRF_MODEM_LIB */
}
/* Application Event Manager handler. Puts event data into messages and adds them to the
* application message queue.
*/
static bool app_event_handler(const struct app_event_header *aeh)
{
struct app_msg_data msg = {0};
bool enqueue_msg = false;
if (is_cloud_module_event(aeh)) {
struct cloud_module_event *evt = cast_cloud_module_event(aeh);
msg.module.cloud = *evt;
enqueue_msg = true;
}
if (is_app_module_event(aeh)) {
struct app_module_event *evt = cast_app_module_event(aeh);
msg.module.app = *evt;
enqueue_msg = true;
}
if (is_data_module_event(aeh)) {
struct data_module_event *evt = cast_data_module_event(aeh);
msg.module.data = *evt;
enqueue_msg = true;
}
if (is_sensor_module_event(aeh)) {
struct sensor_module_event *evt = cast_sensor_module_event(aeh);
msg.module.sensor = *evt;
enqueue_msg = true;
}
if (is_util_module_event(aeh)) {
struct util_module_event *evt = cast_util_module_event(aeh);
msg.module.util = *evt;
enqueue_msg = true;
}
if (is_modem_module_event(aeh)) {
struct modem_module_event *evt = cast_modem_module_event(aeh);
msg.module.modem = *evt;
enqueue_msg = true;
}
if (is_ui_module_event(aeh)) {
struct ui_module_event *evt = cast_ui_module_event(aeh);
msg.module.ui = *evt;
enqueue_msg = true;
}
if (is_bms_module_event(aeh)) {
struct bms_module_event *evt = cast_bms_module_event(aeh);
msg.module.bms = *evt;
enqueue_msg = true;
}
if (enqueue_msg) {
int err = module_enqueue_msg(&self, &msg);
if (err) {
LOG_ERR("Message could not be enqueued");
SEND_ERROR(app, APP_EVT_ERROR, err);
}
}
return false;
}
static bool is_agps_processed(void)
{
#if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS)
struct nrf_modem_gnss_agps_data_frame processed;
nrf_cloud_agps_processed(&processed);
if (!processed.sv_mask_ephe) {
return false;
}
#endif /* CONFIG_NRF_CLOUD_AGPS || CONFIG_NRF_CLOUD_PGPS */
return true;
}
static bool request_gnss(void)
{
uint32_t uptime_current_ms = k_uptime_get();
int agps_wait_threshold_ms = CONFIG_APP_REQUEST_GNSS_WAIT_FOR_AGPS_THRESHOLD_SEC *
MSEC_PER_SEC;
if (!IS_ENABLED(CONFIG_APP_REQUEST_GNSS_WAIT_FOR_AGPS)) {
return true;
} else if (agps_wait_threshold_ms < 0) {
/* If CONFIG_APP_REQUEST_GNSS_WAIT_FOR_AGPS_THRESHOLD_SEC is set to -1,
* we need to notify the data module that the application module is awaiting
* A-GPS data in order to request GNSS. If not, GNSS will never be
* requested if the initial A-GPS data request fails.
*/
if (is_agps_processed()) {
return true;
}
SEND_EVENT(app, APP_EVT_AGPS_NEEDED);
return false;
} else if ((agps_wait_threshold_ms < uptime_current_ms) || is_agps_processed()) {
return true;
}
return false;
}
static void data_sample_timer_handler(struct k_timer *timer)
{
ARG_UNUSED(timer);
SEND_EVENT(app, APP_EVT_DATA_GET_ALL);
}
static void waiting_for_movement_handler(struct k_timer *timer)
{
ARG_UNUSED(timer);
SEND_EVENT(app, APP_EVT_ACTIVITY_DETECTION_ENABLE);
}
/* Static module functions. */
static void passive_mode_timers_start_all(void)
{
LOG_DBG("Device mode: Passive");
LOG_DBG("Start movement timeout: %d seconds interval", app_cfg.movement_timeout);
LOG_DBG("%d seconds until movement can trigger a new data sample/publication",
app_cfg.movement_resolution);
k_timer_start(&movement_resolution_timer,
K_SECONDS(app_cfg.movement_resolution),
K_SECONDS(0));
k_timer_start(&movement_timeout_timer,
K_SECONDS(app_cfg.movement_timeout),
K_SECONDS(app_cfg.movement_timeout));
k_timer_stop(&data_sample_timer);
}
static void active_mode_timers_start_all(void)
{
LOG_DBG("Device mode: Active");
LOG_DBG("Start data sample timer: %d seconds interval", app_cfg.active_wait_timeout);
k_timer_start(&data_sample_timer,
K_SECONDS(app_cfg.active_wait_timeout),
K_SECONDS(app_cfg.active_wait_timeout));
k_timer_stop(&movement_resolution_timer);
k_timer_stop(&movement_timeout_timer);
SEND_EVENT(app, APP_EVT_ACTIVITY_DETECTION_DISABLE);
}
static void data_get(void)
{
static bool first = true;
struct app_module_event *app_module_event = new_app_module_event();
size_t count = 0;
/* Set a low sample timeout. If GNSS is requested, the sample timeout will be increased to
* accommodate the GNSS timeout.
*/
app_module_event->timeout = 1;
/* Specify which data that is to be included in the transmission. */
app_module_event->data_list[count++] = APP_DATA_MODEM_DYNAMIC;
app_module_event->data_list[count++] = APP_DATA_BATTERY;
app_module_event->data_list[count++] = APP_DATA_ENVIRONMENTAL;
if (IS_ENABLED(CONFIG_APP_REQUEST_NEIGHBOR_CELLS_DATA) && !app_cfg.no_data.neighbor_cell) {
app_module_event->data_list[count++] = APP_DATA_NEIGHBOR_CELLS;
}
/* The reason for having at least 75 seconds sample timeout when
* requesting GNSS data is that the GNSS module on the nRF9160 modem will always
* search for at least 60 seconds for the first position fix after a reboot. This limit
* is enforced in order to give the modem time to perform scheduled downloads of
* A-GPS data from the GNSS satellites.
*
* However, if A-GPS data has been downloaded via the cloud connection and processed
* before the initial GNSS search, the actual GNSS timeout set by the application is used.
*
* Processing A-GPS before requesting GNSS data is enabled by default,
* and the time that the application will wait for A-GPS data before including GNSS
* in sample requests can be adjusted via the
* CONFIG_APP_REQUEST_GNSS_WAIT_FOR_AGPS_THRESHOLD_SEC Kconfig option. If this option is
* set to -1, the application module will not request GNSS unless A-GPS data has been
* processed.
*
* If A-GPS data has been processed the sample timeout can be ignored as the
* GNSS will most likely time out before the sample timeout expires.
*
* When GNSS is requested, set the sample timeout to (GNSS timeout + 15 seconds)
* to let the GNSS module finish ongoing searches before data is sent to cloud.
*/
if (first) {
if (IS_ENABLED(CONFIG_APP_REQUEST_GNSS_ON_INITIAL_SAMPLING) && request_gnss() &&
!app_cfg.no_data.gnss) {
app_module_event->data_list[count++] = APP_DATA_GNSS;
app_module_event->timeout = MAX(app_cfg.gnss_timeout + 15, 75);
}
app_module_event->data_list[count++] = APP_DATA_MODEM_STATIC;
first = false;
} else {
if (request_gnss() && !app_cfg.no_data.gnss) {
app_module_event->data_list[count++] = APP_DATA_GNSS;
app_module_event->timeout = MAX(app_cfg.gnss_timeout + 15, 75);
}
}
app_module_event->data_list[count++] = APP_DATA_BMS;
/* Set list count to number of data types passed in app_module_event. */
app_module_event->count = count;
app_module_event->type = APP_EVT_DATA_GET;
APP_EVENT_SUBMIT(app_module_event);
}
/* Message handler for STATE_INIT. */
static void on_state_init(struct app_msg_data *msg)
{
if (IS_EVENT(msg, data, DATA_EVT_CONFIG_INIT)) {
/* Keep a copy of the new configuration. */
app_cfg = msg->module.data.data.cfg;
if (app_cfg.active_mode) {
active_mode_timers_start_all();
} else {
passive_mode_timers_start_all();
}
state_set(STATE_RUNNING);
sub_state_set(app_cfg.active_mode ? SUB_STATE_ACTIVE_MODE :
SUB_STATE_PASSIVE_MODE);
}
}
/* Message handler for STATE_RUNNING. */
static void on_state_running(struct app_msg_data *msg)
{
if (IS_EVENT(msg, cloud, CLOUD_EVT_CONNECTED)) {
data_get();
}
if (IS_EVENT(msg, app, APP_EVT_DATA_GET_ALL)) {
data_get();
}
}
/* Message handler for SUB_STATE_PASSIVE_MODE. */
void on_sub_state_passive(struct app_msg_data *msg)
{
if (IS_EVENT(msg, data, DATA_EVT_CONFIG_READY)) {
/* Keep a copy of the new configuration. */
app_cfg = msg->module.data.data.cfg;
if (app_cfg.active_mode) {
active_mode_timers_start_all();
sub_state_set(SUB_STATE_ACTIVE_MODE);
return;
}
passive_mode_timers_start_all();
}
if ((IS_EVENT(msg, ui, UI_EVT_BUTTON_DATA_READY)) ||
(IS_EVENT(msg, sensor, SENSOR_EVT_MOVEMENT_DATA_READY))) {
if (IS_EVENT(msg, ui, UI_EVT_BUTTON_DATA_READY) &&
msg->module.ui.data.ui.button_number != 2) {
return;
}
/* Trigger a sample request if button 2 has been pushed on the DK or activity has
* been detected. The data request can only be triggered if the movement
* resolution timer has timed out.
*/
if (k_timer_remaining_get(&movement_resolution_timer) == 0) {
data_sample_timer_handler(NULL);
passive_mode_timers_start_all();
}
}
}
/* Message handler for SUB_STATE_ACTIVE_MODE. */
static void on_sub_state_active(struct app_msg_data *msg)
{
if (IS_EVENT(msg, data, DATA_EVT_CONFIG_READY)) {
/* Keep a copy of the new configuration. */
app_cfg = msg->module.data.data.cfg;
if (!app_cfg.active_mode) {
passive_mode_timers_start_all();
sub_state_set(SUB_STATE_PASSIVE_MODE);
return;
}
active_mode_timers_start_all();
}
}
/* Message handler for all states. */
static void on_all_events(struct app_msg_data *msg)
{
if (IS_EVENT(msg, util, UTIL_EVT_SHUTDOWN_REQUEST)) {
k_timer_stop(&data_sample_timer);
k_timer_stop(&movement_timeout_timer);
k_timer_stop(&movement_resolution_timer);
SEND_SHUTDOWN_ACK(app, APP_EVT_SHUTDOWN_READY, self.id);
state_set(STATE_SHUTDOWN);
}
}
void main(void)
{
int err;
struct app_msg_data msg;
if (!IS_ENABLED(CONFIG_LWM2M_CARRIER) && !IS_ENABLED(CONFIG_NRF_CLOUD_FOTA)) {
handle_nrf_modem_lib_init_ret();
}
if (app_event_manager_init()) {
/* Without the Application Event Manager, the application will not work
* as intended. A reboot is required in an attempt to recover.
*/
LOG_ERR("Application Event Manager could not be initialized, rebooting...");
k_sleep(K_SECONDS(5));
sys_reboot(SYS_REBOOT_COLD);
} else {
module_set_state(MODULE_STATE_READY);
SEND_EVENT(app, APP_EVT_START);
}
self.thread_id = k_current_get();
err = module_start(&self);
if (err) {
LOG_ERR("Failed starting module, error: %d", err);
SEND_ERROR(app, APP_EVT_ERROR, err);
}
while (true) {
module_get_next_msg(&self, &msg);
switch (state) {
case STATE_INIT:
on_state_init(&msg);
break;
case STATE_RUNNING:
switch (sub_state) {
case SUB_STATE_ACTIVE_MODE:
on_sub_state_active(&msg);
break;
case SUB_STATE_PASSIVE_MODE:
on_sub_state_passive(&msg);
break;
default:
LOG_WRN("Unknown application sub state");
break;
}
on_state_running(&msg);
break;
case STATE_SHUTDOWN:
/* The shutdown state has no transition. */
break;
default:
LOG_WRN("Unknown application state");
break;
}
on_all_events(&msg);
}
}
APP_EVENT_LISTENER(MODULE, app_event_handler);
APP_EVENT_SUBSCRIBE_EARLY(MODULE, cloud_module_event);
APP_EVENT_SUBSCRIBE(MODULE, app_module_event);
APP_EVENT_SUBSCRIBE(MODULE, data_module_event);
APP_EVENT_SUBSCRIBE(MODULE, util_module_event);
APP_EVENT_SUBSCRIBE_FINAL(MODULE, ui_module_event);
APP_EVENT_SUBSCRIBE_FINAL(MODULE, sensor_module_event);
APP_EVENT_SUBSCRIBE_FINAL(MODULE, modem_module_event);
APP_EVENT_SUBSCRIBE_EARLY(MODULE, bms_module_event);
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <stdio.h>
#include "app_module_event.h"
#include "common_module_event.h"
static char *type2str(enum app_module_data_type type)
{
switch (type) {
case APP_DATA_ENVIRONMENTAL:
return "ENV";
case APP_DATA_MOVEMENT:
return "MOVE";
case APP_DATA_MODEM_STATIC:
return "MOD_STAT";
case APP_DATA_MODEM_DYNAMIC:
return "MOD_DYN";
case APP_DATA_BATTERY:
return "BAT";
case APP_DATA_GNSS:
return "GNSS";
case APP_DATA_NEIGHBOR_CELLS:
return "NEIGHBOR_CELLS";
case APP_DATA_BMS:
return "BMS_DATA";
default:
return "Unknown type";
}
}
static char *get_evt_type_str(enum app_module_event_type type)
{
switch (type) {
case APP_EVT_DATA_GET:
return "APP_EVT_DATA_GET";
case APP_EVT_CONFIG_GET:
return "APP_EVT_CONFIG_GET";
case APP_EVT_ACTIVITY_DETECTION_ENABLE:
return "APP_EVT_ACTIVITY_DETECTION_ENABLE";
case APP_EVT_ACTIVITY_DETECTION_DISABLE:
return "APP_EVT_ACTIVITY_DETECTION_DISABLE";
case APP_EVT_AGPS_NEEDED:
return "APP_EVT_AGPS_NEEDED";
case APP_EVT_DATA_GET_ALL:
return "APP_EVT_DATA_GET_ALL";
case APP_EVT_START:
return "APP_EVT_START";
case APP_EVT_LTE_CONNECT:
return "APP_EVT_LTE_CONNECT";
case APP_EVT_LTE_DISCONNECT:
return "APP_EVT_LTE_DISCONNECT";
case APP_EVT_SHUTDOWN_READY:
return "APP_EVT_SHUTDOWN_READY";
case APP_EVT_ERROR:
return "APP_EVT_ERROR";
default:
return "Unknown event";
}
}
static void log_event(const struct app_event_header *aeh)
{
const struct app_module_event *event = cast_app_module_event(aeh);
char data_types[50] = "\0";
if (event->type == APP_EVT_ERROR) {
APP_EVENT_MANAGER_LOG(aeh, "%s - Error code %d",
get_evt_type_str(event->type), event->data.err);
} else if (event->type == APP_EVT_DATA_GET) {
for (int i = 0; i < event->count; i++) {
strcat(data_types, type2str(event->data_list[i]));
if (i == event->count - 1) {
break;
}
strcat(data_types, ", ");
}
APP_EVENT_MANAGER_LOG(aeh, "%s - Requested data types (%s)",
get_evt_type_str(event->type), log_strdup(data_types));
} else {
APP_EVENT_MANAGER_LOG(aeh, "%s", get_evt_type_str(event->type));
}
}
#if defined(CONFIG_PROFILER)
static void profile_event(struct log_event_buf *buf,
const struct app_event_header *aeh)
{
const struct app_module_event *event = cast_app_module_event(aeh);
#if defined(CONFIG_PROFILER_EVENT_TYPE_STRING)
profiler_log_encode_string(buf, get_evt_type_str(event->type));
#else
profiler_log_encode_uint8(buf, event->type);
#endif
}
COMMON_APP_EVENT_INFO_DEFINE(app_module_event,
profile_event);
#endif /* CONFIG_PROFILER */
COMMON_APP_EVENT_TYPE_DEFINE(app_module_event,
log_event,
&app_module_event_info,
APP_EVENT_FLAGS_CREATE(
IF_ENABLED(CONFIG_APP_EVENTS_LOG,
(APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE))));
//************************
#include <stdio.h>
//**********************************
#include "bms_module_event.h"
#include "common_module_event.h"
//*************************************
static char *get_evt_type_str(enum bms_module_event_type type)
{
switch (type) {
case BMS_PIN_SUCCESS:return "BMS_PIN_HARDWARE_CONFIGURATION_OK";
case BMS_PIN_FAIL: return "BS_PIN_HARDWARE_CONFIGURATION_FAIL";
case BMS_DETACHED: return "BMS_REMOVED";
case BMS_ATTACHED:
return "BMS_ATTACHED";
case BMS_DATA_ERROR:
return "BMS_EVT_ERROR";
case BMS_DATA_READY:
return "BMS_DATA_READY";
default:
return "Unknown BMS event";
}
}
static void log_event(const struct app_event_header *eh)
{
const struct bms_module_event *event = cast_bms_module_event(eh);
char event_name[50] = "\0";
strcpy(event_name, get_evt_type_str(event->type));
if (event->type == BMS_DATA_ERROR) {
} else if (event->type == BMS_DATA_READY) {
}
else if (event->type == BMS_ATTACHED) {
}
}
#if defined(CONFIG_PROFILER)
static void profile_event(struct log_event_buf *buf,
const struct app_event_header *aeh)
{
const struct bms_module_event *event = cast_bms_module_event(aeh);
#if defined(CONFIG_PROFILER_EVENT_TYPE_STRING)
profiler_log_encode_string(buf, get_evt_type_str(event->type));
#else
profiler_log_encode_uint8(buf, event->type);
#endif
}
COMMON_APP_EVENT_INFO_DEFINE(bms_module_event,
profile_event);
#endif /* CONFIG_PROFILER */
COMMON_APP_EVENT_TYPE_DEFINE(bms_module_event,
log_event,
&bms_module_event_info,
APP_EVENT_FLAGS_CREATE(
IF_ENABLED(CONFIG_BMS_EVENTS_LOG,
(APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE))));
//***************************************************************************************
LOG_MODULE_REGISTER(bms_module, CONFIG_BMS_MODULE_LOG_LEVEL);
//********************************************************
struct bms_msg_data {
union {
struct app_module_event app;
} module;
};
/* BMS module super states. */
static enum state_type {
BMS_INIT,
BMS_DETECT,
BMS_RUNNING,
} state;
/* Bms module message queue. */
#define BMS_QUEUE_ENTRY_COUNT 10
#define BMS_QUEUE_BYTE_ALIGNMENT 4
K_MSGQ_DEFINE(msgq_bms, sizeof(struct bms_msg_data),
BMS_QUEUE_ENTRY_COUNT, BMS_QUEUE_BYTE_ALIGNMENT);
static struct module_data self = {
.name = "bms_DALY",
.msg_q = &msgq_bms,
.supports_shutdown = true,
};
/* Convenience functions used in internal state handling. */
static char *state2str(enum state_type new_state)
{
switch (new_state) {
case BMS_INIT:
return "STATE_INIT";
case BMS_DETECT:
return "BMS DETECTED";
case BMS_RUNNING:
return "STATE_RUNNING";
default:
return "Unknown";
}
}
static void state_set(enum state_type new_state)
{
if (new_state == state) {
LOG_DBG("State: %s", state2str(state));
return;
}
LOG_DBG("State transition %s --> %s",
state2str(state),
state2str(new_state));
state = new_state;
}
/* Handlers */
static bool app_event_handler(const struct app_event_header *eh)
{
struct bms_msg_data msg = {0};
bool enqueue_msg = false;
if (is_app_module_event(eh)) {
struct app_module_event *event = cast_app_module_event(eh);
msg.module.app = *event;
enqueue_msg = true;
}
if (enqueue_msg) {
int err = module_enqueue_msg(&self, &msg);
if (err) {
LOG_ERR("Message could not be enqueued");
SEND_ERROR(bms, BMS_DATA_ERROR, err);
}
}
return false;
}
/* Message handler for STATE_INIT. */
static void on_state_init(struct bms_msg_data *msg)
{ int ret;
struct bms_module_event *bms_init_event = new_bms_module_event();
if (IS_EVENT(msg, app, APP_EVT_START)){
// my code here
if((detect_pin_flag == true)&&(reset_pin_flag == true)){bms_init_event->type=BMS_PIN_SUCCESS;state_set(BMS_DETECT);}
else{bms_init_event->type=BMS_PIN_FAIL;}
EVENT_SUBMIT(bms_init_event);
}
}
static void detect_bms(struct bms_msg_data *msg)
{
struct bms_module_event *bms_detect_event = new_bms_module_event();
if(IS_EVENT(msg, app, APP_EVT_CONFIG_GET))
{
// my code
if(....)bms_detect_event->type = BMS_ATTACHED;
else{bms_detect_event->type = BMS_DETACHED;}
}
EVENT_SUBMIT(bms_detect_event);
}
/* Message handler for STATE_RUNNING. */
static void on_state_running(struct bms_msg_data *msg)
{
struct bms_module_event *bms_run_event = new_bms_module_event();
if (IS_EVENT(msg, app, APP_EVT_DATA_GET)){
// my code
bms_run_event->type = BMS_DATA_READY;
}
EVENT_SUBMIT(bms_run_event);
}
static void module_thread_fn(void)
{
int err;
struct bms_msg_data msg;
self.thread_id = k_current_get();
err = module_start(&self);
if (err) {
LOG_ERR("Failed starting module, error: %d", err);
SEND_ERROR(bms, BMS_DATA_ERROR, err);
}
LOG_DBG("BMS Thread Started: %d", err);
while (true) {
module_get_next_msg(&self, &msg);
LOG_WRN("New Message in BMS Thread");
switch (state) {
case BMS_INIT:
on_state_init(&msg);
break;
case BMS_DETECT:
detect_bms(&msg);
break;
case BMS_RUNNING:
on_state_running(&msg);
break;
default:
LOG_WRN("Unknown BMS module state.");
break;
}
}
}
//*******************************************************************
K_THREAD_DEFINE(bms_module_thread, CONFIG_BMS_THREAD_STACK_SIZE,
module_thread_fn, NULL, NULL, NULL,
K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0);
//*******************************************************************
APP_EVENT_LISTENER(MODULE, app_event_handler);
APP_EVENT_SUBSCRIBE(MODULE, app_module_event);
//*******************************************************************
2022-04-26T14:23:59.494Z DEBUG Application data folder: C:\Users\Andrew.McComas\AppData\Roaming\nrfconnect\pc-nrfconnect-linkmonitor
2022-04-26T14:23:59.564Z DEBUG App pc-nrfconnect-linkmonitor v2.0.1 official
2022-04-26T14:23:59.564Z DEBUG App path: C:\Users\Andrew.McComas\.nrfconnect-apps\node_modules\pc-nrfconnect-linkmonitor
2022-04-26T14:23:59.564Z DEBUG nRFConnect 3.11.0, required by the app is (^3.8.0)
2022-04-26T14:23:59.564Z DEBUG nRFConnect path: C:\Users\Andrew.McComas\AppData\Local\Programs\nrfconnect\resources\app.asar
2022-04-26T14:23:59.564Z DEBUG HomeDir: C:\Users\Andrew.McComas
2022-04-26T14:23:59.564Z DEBUG TmpDir: C:\Users\ANDREW~1.MCC\AppData\Local\Temp
2022-04-26T14:23:59.566Z INFO Using nrf-device-lib-js version: 0.4.5
2022-04-26T14:23:59.567Z INFO Using nrf-device-lib version: 0.11.0
2022-04-26T14:23:59.567Z INFO Using nrfjprog DLL version: 10.15.1
2022-04-26T14:23:59.567Z INFO Using JLink version: JLink_V7.58b
2022-04-26T14:24:03.578Z INFO Modem port is opened
2022-04-26T14:24:13.951Z DEBUG modem << ing Zephyr OS build v2.7.99-ncs1-2195-g186cf4539e5a ***
2022-04-26T14:24:13.969Z DEBUG modem << I: Starting bootloader
2022-04-26T14:24:13.973Z DEBUG modem << I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
2022-04-26T14:24:13.975Z DEBUG modem << I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
2022-04-26T14:24:13.976Z DEBUG modem << I: Boot source: none
2022-04-26T14:24:13.980Z DEBUG modem << I: Swap type: none
2022-04-26T14:24:14.059Z DEBUG modem << I: Bootloader chainload address offset: 0x10000
2022-04-26T14:24:14.065Z DEBUG modem << I: Jumping to the first image slot
2022-04-26T14:24:14.542Z DEBUG modem << *** Booting Zephyr OS build v2.7.99-ncs1-2195-g186cf4539e5a ***
2022-04-26T14:24:14.554Z DEBUG modem << [00:00:00.207,611] [0m<dbg> watchdog: watchdog_timeout_install: Watchdog timeout installed. Timeout: 60[0m
2022-04-26T14:24:14.559Z DEBUG modem << [00:00:00.217,163] [0m<dbg> watchdog: watchdog_start: Watchdog started[0m
2022-04-26T14:24:14.566Z DEBUG modem << [00:00:00.223,907] [0m<dbg> watchdog: watchdog_feed_enable: Watchdog feed enabled. Timeout: 30000[0m
2022-04-26T14:24:14.597Z DEBUG modem << [00:00:00.233,337] [0m<inf> app_event_manager: APP_EVT_START[0m
2022-04-26T14:24:14.599Z DEBUG modem << [00:00:00.239,227] [0m<dbg> gnss_module: state_set: State: STATE_INIT[0m
2022-04-26T14:24:14.603Z DEBUG modem << [00:00:00.245,910] [0m<dbg> ui_module: state_set: State transition STATE_INIT --> STATE_RUNNING[0m
2022-04-26T14:24:14.604Z DEBUG modem << [00:00:00.254,760] [0m<dbg> ui_module: sub_state_set: Sub state: SUB_STATE_ACTIVE[0m
2022-04-26T14:24:14.610Z DEBUG modem << [00:00:00.262,451] [0m<dbg> ui_module: sub_sub_state_set: Sub state: SUB_SUB_STATE_GNSS_INACTIVE[0m
2022-04-26T14:24:14.625Z DEBUG modem << [00:00:00.271,484] [0m<dbg> util_module: state_set: State: STATE_INIT[0m
2022-04-26T14:24:14.627Z DEBUG modem << [00:00:00.278,717] [1;31m<err> os: ***** USAGE FAULT *****[0m
2022-04-26T14:24:14.629Z DEBUG modem << [00:00:00.284,332] [1;31m<err> os: Stack overflow (context area not valid)[0m
2022-04-26T14:24:14.640Z DEBUG modem << [00:00:00.291,595] [1;31m<err> os: r0/a1: 0x0c060050 r1/a2: 0xfb7f9ff7 r2/a3: 0x0e00d620[0m
2022-04-26T14:24:14.643Z DEBUG modem << [00:00:00.300,323] [1;31m<err> os: r3/a4: 0x5df7ffff r12/ip: 0x000214ee r14/lr: 0x61000200[0m
2022-04-26T14:24:14.647Z DEBUG modem << [00:00:00.309,020] [1;31m<err> os: xpsr: 0x00000000[0m
2022-04-26T14:24:14.659Z DEBUG modem << [00:00:00.314,300] [1;31m<err> os: s[ 0]: 0x00000000 s[ 1]: 0x00000000 s[ 2]: 0x00000000 s[ 3]: 0x00000000[0m
2022-04-26T14:24:14.671Z DEBUG modem << [00:00:00.324,768] [1;31m<err> os: s[ 4]: 0x00000000 s[ 5]: 0x00000000 s[ 6]: 0x00000000 s[ 7]: 0x00000000[0m
2022-04-26T14:24:14.679Z DEBUG modem << [00:00:00.335,235] [1;31m<err> os: s[ 8]: 0x00000000 s[ 9]: 0x00000000 s[10]: 0x00000000 s[11]: 0x00000000[0m
2022-04-26T14:24:14.690Z DEBUG modem << [00:00:00.345,733] [1;31m<err> os: s[12]: 0x00000000 s[13]: 0x00000000 s[14]: 0x00000000 s[15]: 0x00000000[0m
2022-04-26T14:24:14.695Z DEBUG modem << [00:00:00.356,170] [1;31m<err> os: fpscr: 0x01c10400[0m
2022-04-26T14:24:14.705Z DEBUG modem << [00:00:00.361,389] [1;31m<err> os: Faulting instruction address (r15/pc): 0x00000000[0m
2022-04-26T14:24:14.712Z DEBUG modem << [00:00:00.369,354] [1;31m<err> os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0[0m
2022-04-26T14:24:14.724Z DEBUG modem << [00:00:00.377,288] [1;31m<err> os: Current thread: 0x2000d2b0 (unknown)[0m
2022-04-26T14:24:14.727Z DEBUG modem << [00:00:00.384,155] [0m<dbg> util_module: state_set: State transition STATE_INIT --> STATE_REBOOT_PENDING[0m
2022-04-26T14:24:14.737Z DEBUG modem << [00:00:00.393,829] [0m<inf> app_event_manager: UTIL_EVT_SHUTDOWN_REQUEST[0m
2022-04-26T14:24:14.743Z DEBUG modem << [00:00:00.400,848] [0m<dbg> ui_module: state_set: State transition STATE_RUNNING --> STATE_SHUTDOWN[0m
2022-04-26T14:24:14.755Z DEBUG modem << [00:00:00.410,278] [0m<dbg> gnss_module: state_set: State transition STATE_INIT --> STATE_SHUTDOWN[0m
2022-04-26T14:24:14.759Z DEBUG modem << [00:00:00.419,647] [0m<inf> app_event_manager: UI_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:14.772Z DEBUG modem << [00:00:00.426,269] [1;33m<wrn> modules_common: Module "ui" shutdown registered[0m
2022-04-26T14:24:14.775Z DEBUG modem << [00:00:00.433,807] [0m<inf> app_event_manager: GNSS_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:14.781Z DEBUG modem << [00:00:00.440,673] [1;33m<wrn> modules_common: Module "gnss" shutdown registered[0m
2022-04-26T14:24:14.789Z DEBUG modem << [00:00:00.448,822] [0m<inf> app_event_manager: APP_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:14.797Z DEBUG modem << [00:00:00.455,566] [1;33m<wrn> modules_common: Module "app" shutdown registered[0m
2022-04-26T14:24:14.805Z DEBUG modem << [00:00:00.463,531] [0m<dbg> main: state_set: State transition STATE_INIT --> STATE_SHUTDOWN[0m
2022-04-26T14:24:14.812Z DEBUG modem << [00:00:00.472,137] [0m<dbg> cloud_module: state_set: State: STATE_LTE_INIT[0m
2022-04-26T14:24:14.821Z DEBUG modem << [00:00:00.479,217] [0m<dbg> cloud_module: sub_state_set: Sub state: SUB_STATE_CLOUD_DISCONNECTED[0m
2022-04-26T14:24:14.828Z DEBUG modem << [00:00:00.488,403] [0m<inf> app_event_manager: CLOUD_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:14.839Z DEBUG modem << [00:00:00.495,422] [1;33m<wrn> modules_common: Module "cloud" shutdown registered[0m
2022-04-26T14:24:14.844Z DEBUG modem << [00:00:00.503,387] [0m<dbg> data_module: state_set: State: STATE_CLOUD_DISCONNECTED[0m
2022-04-26T14:24:14.855Z DEBUG modem << [00:00:00.511,444] [0m<dbg> date_time: date_time_core_register_handler: Registering handler 0x47913[0m
2022-04-26T14:24:14.861Z DEBUG modem << [00:00:00.520,721] [0m<dbg> data_module: config_print_all: Device mode: Active[0m
2022-04-26T14:24:14.871Z DEBUG modem << [00:00:00.528,167] [0m<dbg> data_module: config_print_all: Active wait timeout: 120[0m
2022-04-26T14:24:14.878Z DEBUG modem << [00:00:00.536,102] [0m<dbg> data_module: config_print_all: Movement resolution: 120[0m
2022-04-26T14:24:14.888Z DEBUG modem << [00:00:00.544,036] [0m<dbg> data_module: config_print_all: Movement timeout: 3600[0m
2022-04-26T14:24:14.892Z DEBUG modem << [00:00:00.551,696] [0m<dbg> data_module: config_print_all: GPS timeout: 60[0m
2022-04-26T14:24:14.909Z DEBUG modem << [00:00:00.558,837] [0m<dbg> data_module: config_print_all: Accelerometer threshold: 10.00[0m
2022-04-26T14:24:14.912Z DEBUG modem << [00:00:00.567,291] [0m<dbg> data_module: config_print_all: Requesting of neighbor cell data is enabled[0m
2022-04-26T14:24:14.922Z DEBUG modem << [00:00:00.576,873] [0m<dbg> data_module: config_print_all: Requesting of GNSS data is enabled[0m
2022-04-26T14:24:14.925Z DEBUG modem << [00:00:00.585,693] [0m<inf> app_event_manager: DATA_EVT_CONFIG_INIT[0m
2022-04-26T14:24:14.933Z DEBUG modem << [00:00:00.592,163] [0m<dbg> ui_module: sub_state_set: Sub state: SUB_STATE_ACTIVE[0m
2022-04-26T14:24:14.944Z DEBUG modem << [00:00:00.600,311] [0m<dbg> modem_module: state_set: State transition STATE_INIT --> STATE_DISCONNECTED[0m
2022-04-26T14:24:14.954Z DEBUG modem << [00:00:00.609,893] [0m<inf> app_event_manager: MODEM_EVT_INITIALIZED[0m
2022-04-26T14:24:14.960Z DEBUG modem << [00:00:00.616,851] [0m<dbg> gnss_module: lna_configure: MAGPIO command: AT%XMAGPIO=1,0,0,1,1,1574,1577[0m
2022-04-26T14:24:14.974Z DEBUG modem << [00:00:00.626,312] [0m<dbg> gnss_module: lna_configure: COEX0 command: AT%XCOEX0=1,1,1565,1586[0m
2022-04-26T14:24:14.989Z DEBUG modem << [00:00:00.635,284] [0m<dbg> sensor_module: state_set: State: STATE_INIT[0m[00:00:00.642,242] [0m<dbg> gnss_module: state_set: State transition STATE_SHUTDOWN --> STATE_RUNNING[0m
2022-04-26T14:24:14.992Z DEBUG modem << [00:00:00.652,008] [0m<inf> app_event_manager: SENSOR_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:15.007Z DEBUG modem << [00:00:00.658,996] [1;33m<wrn> modules_common: Module "sensor" shutdown registered[0m
2022-04-26T14:24:15.010Z DEBUG modem << [00:00:00.666,961] [0m<dbg> cloud_module: state_set: State transition STATE_LTE_INIT --> STATE_SHUTDOWN[0m
2022-04-26T14:24:15.022Z DEBUG modem << [00:00:00.676,788] [0m<inf> app_event_manager: DATA_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:15.024Z DEBUG modem << [00:00:00.683,532] [1;33m<wrn> modules_common: Module "data" shutdown registered[0m
2022-04-26T14:24:15.039Z DEBUG modem << [00:00:00.691,619] [0m<dbg> sensor_module: state_set: State transition STATE_INIT --> STATE_SHUTDOWN[0m
2022-04-26T14:24:15.045Z DEBUG modem << [00:00:00.701,049] [0m<dbg> data_module: state_set: State transition STATE_CLOUD_DISCONNECTED --> STATE_SHUTDOWN[0m
2022-04-26T14:24:15.060Z DEBUG modem << [00:00:00.719,421] [0m<dbg> modem_module: configure_low_power: PSM requested[0m
2022-04-26T14:24:15.112Z DEBUG modem << [00:00:00.772,521] [0m<inf> app_event_manager: MODEM_EVT_LTE_CONNECTING[0m
2022-04-26T14:24:15.122Z DEBUG modem << [00:00:00.779,418] [0m<dbg> ui_module: state_set: State transition STATE_SHUTDOWN --> STATE_LTE_CONNECTING[0m
2022-04-26T14:24:15.126Z DEBUG modem << +CEREG: 0
2022-04-26T14:24:15.142Z DEBUG modem << [00:00:00.792,602] [0m<dbg> modem_module: lte_evt_handler: LTE cell changed: Cell ID: -1, Tracking area: -1[0m
2022-04-26T14:24:15.144Z DEBUG modem << [00:00:00.802,642] [0m<inf> app_event_manager: MODEM_EVT_LTE_CELL_UPDATE[0m
2022-04-26T14:24:15.352Z DEBUG modem << [00:00:01.009,124] [0m<dbg> modem_module: state_set: State transition STATE_DISCONNECTED --> STATE_SHUTDOWN[0m
2022-04-26T14:24:15.359Z DEBUG modem << [00:00:01.019,134] [0m<inf> app_event_manager: MODEM_EVT_SHUTDOWN_READY[0m
2022-04-26T14:24:15.370Z DEBUG modem << [00:00:01.026,184] [1;33m<wrn> modules_common: Module "modem" shutdown registered[0m