If you improve the AWS_IoT sample and send a message to Device Shadow, the nRF9160 will reset.
I am using nRF9160DK.
I got the debug logs, but couldn't figure out the cause.
The source code and execution status are attached below.
main.c
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <dk_buttons_and_leds.h>
#if defined(CONFIG_NRF_MODEM_LIB)
#include <modem/lte_lc.h>
#include <modem/nrf_modem_lib.h>
#include <modem/modem_info.h>
#include <nrf_modem.h>
#endif
#include <net/aws_iot.h>
#include <zephyr/sys/reboot.h>
#include <date_time.h>
#include <zephyr/dfu/mcuboot.h>
#include <cJSON.h>
#include <cJSON_os.h>
#include <zephyr/logging/log.h>
#if defined(CONFIG_AWS_IOT_SAMPLE_DEVICE_ID_USE_HW_ID)
#include <hw_id.h>
#endif
LOG_MODULE_REGISTER( aws_iot_sample, CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL );
BUILD_ASSERT( !IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT), "This sample does not support LTE auto-init and connect" );
#define APP_TOPICS_COUNT CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT
static struct k_work shadow_update_work;
static struct k_work reported_work;
static struct k_work_delayable connect_work;
static bool cloud_connected;
static bool ledState = false;
static K_SEM_DEFINE( lte_connected, 0, 1 );
static int json_add_obj( cJSON *parent, const char *str, cJSON *item ) {
cJSON_AddItemToObject( parent, str, item );
return 0;
}
static int json_add_str( cJSON *parent, const char *str, const char *item ) {
cJSON *json_str;
json_str = cJSON_CreateString( item );
if ( json_str == NULL ) return -ENOMEM;
return json_add_obj( parent, str, json_str );
}
static int json_add_number( cJSON *parent, const char *str, double item ) {
cJSON *json_num;
json_num = cJSON_CreateNumber( item );
if ( json_num == NULL ) return -ENOMEM;
return json_add_obj( parent, str, json_num );
}
static int shadow_update( bool report ) {
int err;
char *message;
cJSON *root_obj = cJSON_CreateObject( );
cJSON *state_obj = cJSON_CreateObject( );
cJSON *reported_obj = cJSON_CreateObject( );
cJSON *desired_obj = cJSON_CreateObject( );
if ( root_obj == NULL || state_obj == NULL || reported_obj == NULL ) {
cJSON_Delete( root_obj );
cJSON_Delete( state_obj );
cJSON_Delete( reported_obj );
cJSON_Delete( desired_obj );
err = -ENOMEM;
return err;
}
if ( ledState ) {
err += json_add_str( reported_obj, "led", "ON" );
if ( !report ) err += json_add_str( desired_obj, "led", "ON" );
} else {
err += json_add_str( reported_obj, "led", "OFF" );
if ( !report ) err += json_add_str( desired_obj, "led", "OFF" );
}
err += json_add_obj( state_obj, "reported", reported_obj );
if ( !report ) err += json_add_obj( state_obj, "desired", desired_obj );
err += json_add_obj( root_obj, "state", state_obj );
if ( err ) {
LOG_ERR( "json_add, error: %d", err );
goto cleanup;
}
message = cJSON_Print( root_obj );
if ( message == NULL ) {
LOG_ERR( "cJSON_Print, error: returned NULL" );
err = -ENOMEM;
goto cleanup;
}
struct aws_iot_data tx_data = {
.qos = MQTT_QOS_0_AT_MOST_ONCE,
.topic.type = AWS_IOT_SHADOW_TOPIC_UPDATE,
.ptr = message,
.len = strlen( message )
};
LOG_INF( "Publishing: %s to AWS IoT broker", message );
err = aws_iot_send( &tx_data );
if ( err ) LOG_ERR("aws_iot_send, error: %d", err);
cJSON_FreeString( message );
cleanup:
cJSON_Delete( root_obj );
cJSON_Delete( state_obj );
cJSON_Delete( reported_obj );
cJSON_Delete( desired_obj );
return err;
}
static void connect_work_fn( struct k_work *work ) {
int err;
// 出力できていたら終了
if ( cloud_connected ) return;
LOG_INF( "Start AWS IoT Connect" );
err = aws_iot_connect( NULL );
if ( err ) LOG_ERR("aws_iot_connect, error: %d", err);
LOG_INF( "Next connection retry in %d seconds", CONFIG_AWS_IOT_SAMPLE_CONNECTION_RETRY_TIMEOUT_SECONDS );
k_work_schedule( &connect_work, K_SECONDS( CONFIG_AWS_IOT_SAMPLE_CONNECTION_RETRY_TIMEOUT_SECONDS ));
}
static void shadow_update_work_fn( struct k_work *work ) {
int err;
// 接続できていなかったら終了
if ( !cloud_connected ) return;
err = shadow_update( false );
if ( err ) LOG_ERR("shadow_update, error: %d", err);
}
static void reported_work_fn( struct k_work *work ) {
int err;
// 接続できていなかったら終了
if ( !cloud_connected ) return;
err = shadow_update( true );
if ( err ) LOG_ERR("shadow_update, error: %d", err);
}
static void print_received_data( const char *buf, const char *topic, size_t topic_len ) {
// subscribe受診時の処理
if ( strcmp( topic, "$aws/things/cts-lte-sample/shadow/update/delta" ) != 0 ) return;
char *str = NULL;
cJSON *root_obj = NULL;
cJSON *state_obj = NULL;
cJSON *led_obj = NULL;
LOG_INF( "Data received from AWS IoT console: Topic: %s", topic );
root_obj = cJSON_Parse( buf );
str = cJSON_Print( root_obj );
if ( str == NULL ) {
LOG_ERR( "Failed to print JSON object" );
goto clean_exit;
}
LOG_INF( "Message: %s", str );
state_obj = cJSON_GetObjectItem( root_obj, "state" );
led_obj = cJSON_GetObjectItem( state_obj, "led" );
if (( root_obj == NULL ) || ( state_obj == NULL ) || ( led_obj == NULL )) {
LOG_ERR( "cJSON Parse failure" );
return;
}
ledState = strcmp( cJSON_GetStringValue( led_obj ), "ON" ) == 0;
dk_set_led( DK_LED1, ledState );
k_work_submit( &reported_work );
cJSON_FreeString( str );
clean_exit:
cJSON_Delete( root_obj );
cJSON_Delete( state_obj );
cJSON_Delete( led_obj );
}
void aws_iot_event_handler( const struct aws_iot_evt *const evt ) {
switch ( evt->type ) {
case AWS_IOT_EVT_CONNECTING:
LOG_INF( "AWS_IOT_EVT_CONNECTING" );
break;
case AWS_IOT_EVT_CONNECTED:
LOG_INF( "AWS_IOT_EVT_CONNECTED" );
cloud_connected = true;
( void )k_work_cancel_delayable( &connect_work );
dk_set_led( DK_LED2, true );
k_work_submit( &shadow_update_work );
#if defined( CONFIG_NRF_MODEM_LIB )
LOG_INF( "Setting Power Saving Mode" );
int err = lte_lc_psm_req( true );
if ( err ) LOG_ERR("Requesting PSM failed, error: %d", err);
#endif
break;
case AWS_IOT_EVT_READY:
LOG_INF( "AWS_IOT_EVT_READY" );
break;
case AWS_IOT_EVT_DISCONNECTED:
LOG_INF( "AWS_IOT_EVT_DISCONNECTED" );
cloud_connected = false;
k_work_schedule( &connect_work, K_NO_WAIT );
dk_set_led( DK_LED2, false );
break;
case AWS_IOT_EVT_DATA_RECEIVED:
LOG_INF( "AWS_IOT_EVT_DATA_RECEIVED" );
print_received_data( evt->data.msg.ptr, evt->data.msg.topic.str, evt->data.msg.topic.len );
break;
case AWS_IOT_EVT_PUBACK:
LOG_INF( "AWS_IOT_EVT_PUBACK, message ID: %d", evt->data.message_id );
break;
case AWS_IOT_EVT_ERROR:
LOG_INF( "AWS_IOT_EVT_ERROR, %d", evt->data.err );
break;
default:
LOG_WRN( "Unknown AWS IoT event type: %d", evt->type );
break;
}
}
static void work_init( void ) {
k_work_init( &shadow_update_work, shadow_update_work_fn );
k_work_init( &reported_work, reported_work_fn );
k_work_init_delayable( &connect_work, connect_work_fn );
}
#if defined( CONFIG_NRF_MODEM_LIB )
static void lte_handler( const struct lte_lc_evt *const evt ) {
switch ( evt->type ) {
case LTE_LC_EVT_NW_REG_STATUS:
if (( evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME ) &&
( evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING ))
break;
LOG_INF( "Network registration status: %s", evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "Connected - home network" : "Connected - roaming" );
k_sem_give( <e_connected );
break;
case LTE_LC_EVT_PSM_UPDATE:
LOG_INF( "PSM parameter update: TAU: %d, Active time: %d", evt->psm_cfg.tau, evt->psm_cfg.active_time );
break;
case LTE_LC_EVT_EDRX_UPDATE: {
char log_buf[60];
ssize_t len;
len = snprintf( log_buf, sizeof(log_buf), "eDRX parameter update: eDRX: %f, PTW: %f", evt->edrx_cfg.edrx, evt->edrx_cfg.ptw );
if ( len > 0 ) LOG_INF("%s", log_buf);
break;
}
case LTE_LC_EVT_RRC_UPDATE:
LOG_INF( "RRC mode: %s", evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ? "Connected" : "Idle" );
break;
case LTE_LC_EVT_CELL_UPDATE:
LOG_INF( "LTE cell changed: Cell ID: %d, Tracking area: %d", evt->cell.id, evt->cell.tac );
break;
default:
break;
}
}
#endif
// static int app_topics_subscribe( void ) {
// int err;
// static char custom_topic[75] = "my-custom-topic/example";
// static char custom_topic_2[75] = "my-custom-topic/example_2";
// const struct aws_iot_topic_data topics_list[ APP_TOPICS_COUNT ] = {
// [0].str = custom_topic,
// [0].len = strlen(custom_topic),
// [1].str = custom_topic_2,
// [1].len = strlen(custom_topic_2)
// };
// err = aws_iot_subscription_topics_add( topics_list, ARRAY_SIZE(topics_list) );
// if ( err ) LOG_ERR( "aws_iot_subscription_topics_add, error: %d", err );
// return err;
// }
static void button_handler( uint32_t button_state, uint32_t has_changed ) {
switch ( has_changed ) {
case DK_BTN1_MSK:
if ( button_state & DK_BTN1_MSK ) {
// ボタンの変化に伴ってメッセージを送信する
ledState = !ledState;
dk_set_led( DK_LED1, ledState );
k_work_submit( &shadow_update_work );
}
break;
}
}
int main( void ) {
int err;
LOG_INF( "The AWS IoT sample started, version: %s", CONFIG_AWS_IOT_SAMPLE_APP_VERSION );
cJSON_Init( );
if ( dk_leds_init( ) != 0 ) LOG_ERR( "Failed to initialize the LED library" );
if ( dk_buttons_init( button_handler ) != 0 ) LOG_ERR( "Failed to initialize the button library" );
#if defined( CONFIG_NRF_MODEM_LIB )
err = nrf_modem_lib_init( );
if ( err ) {
LOG_ERR( "Modem library initialization failed, error: %d", err );
return 0;
}
#endif
LOG_INF( "AWS IoT Init" );
err = aws_iot_init( NULL, aws_iot_event_handler );
if ( err ) LOG_ERR("AWS IoT library could not be initialized, error: %d", err );
// err = app_topics_subscribe( );
// if ( err ) LOG_ERR( "Adding application specific topics failed, error: %d", err );
LOG_INF( "Work Init" );
work_init( );
#if defined( CONFIG_NRF_MODEM_LIB )
LOG_INF( "Start LTE Connect" );
err = lte_lc_init_and_connect_async( lte_handler );
if ( err ) {
LOG_ERR( "Modem could not be configured, error: %d", err );
return 0;
}
err = modem_info_init( );
if ( err ) LOG_ERR( "Failed initializing modem info module, error: %d", err );
k_sem_take( <e_connected, K_FOREVER );
#endif
k_work_schedule( &connect_work, K_NO_WAIT );
return 0;
}
prj.conf
CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_REBOOT=y # Button and LED support CONFIG_DK_LIBRARY=y # NEWLIB C CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y # Log CONFIG_LOG=y # CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL_INF=y CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL_DBG=y # Network CONFIG_NETWORKING=y CONFIG_NET_NATIVE=n # LTE link control CONFIG_LTE_LINK_CONTROL=y CONFIG_LTE_NETWORK_MODE_LTE_M=y # Modem library CONFIG_NRF_MODEM_LIB=y # AT Host CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_AT_HOST_LIBRARY=y # AWS IoT library CONFIG_AWS_IOT=y CONFIG_AWS_IOT_CLIENT_ID_STATIC="cts-lte-sample" CONFIG_AWS_IOT_BROKER_HOST_NAME="a2dv87z16ohdau-ats.iot.ap-northeast-1.amazonaws.com" CONFIG_AWS_IOT_SEC_TAG=24 CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE=y CONFIG_AWS_IOT_LAST_WILL=y CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE=y CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE=y # MQTT - Maximum MQTT keepalive timeout specified by AWS IoT Core CONFIG_MQTT_KEEPALIVE=1200 # Modem information CONFIG_MODEM_INFO=y # Heap and stacks CONFIG_HEAP_MEM_POOL_SIZE=16384 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 # CJSON CONFIG_CJSON_LIB=y
log(Excerpt)
*** Booting Zephyr OS build v3.3.99-ncs1-1 *** I: The AWS IoT sample started, version: v1.0.0 I: AWS IoT Init I: Work Init I: Start LTE Connect +CEREG: 2,"63E3","06F12505",7 I: LTE cell changed: Cell ID: 116466949, Tracking area: 25571 +CSCON: 1 I: RRC mode: Connected +CEREG: 5,"63E3","06F12505",7,,,"11100000","11100000" I: Network registration status: Connected - roaming I: PSM parameter update: TAU: 3240, Active time: -1 I: Start AWS IoT Connect I: Next connection retry in 30 seconds I: AWS_IOT_EVT_CONNECTING D: IPv4 Address found 52.196.86.12 D: Using send socket timeout of 60 seconds D: AWS IoT broker connection request sent D: MQTT client connected! I: AWS_IOT_EVT_CONNECTED I: Publishing: { "state": { "reported": { "led": "OFF" }, "desired": { "led": "OFF" } } } to AWS IoT broker D: Using message ID 35279 set by the library D: Publishing to topic: $aws/things/cts-lte-sample/shadow/update I: Setting Po*** Booting Zephyr OS build v3.3.99-ncs1-1 *** I: The AWS IoT sample started, version: v1.0.0 I: AWS IoT Init I: Work Init I: Start LTE Connect