NRF52840:Thread communication debugging is restarted

Hi Nordic Team: 

I'm using the coap server example. I created a test task that will always send UDP messages. During the test, I found that the device would restart. Here is the test code I modified, along with the log for RTT when an abnormal restart occurs.I really hope to get your help.Thank you. 

OS: Windows 10

HW: NRF52840 DK    

NCS Version:nRF Connect SDK v2.1.0

/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr/kernel.h>
#include <dk_buttons_and_leds.h>
#include <zephyr/logging/log.h>
#include <zephyr/net/openthread.h>
/*UDP*/
#include <openthread/message.h>
#include <openthread/udp.h>
#include <openthread/ip6.h>
#include <openthread/link.h>

#include <openthread/thread.h>

#include "ot_coap_utils.h"

LOG_MODULE_REGISTER(coap_server, CONFIG_COAP_SERVER_LOG_LEVEL);

#define OT_CONNECTION_LED DK_LED1
#define PROVISIONING_LED DK_LED3
#define LIGHT_LED DK_LED4

static struct k_work provisioning_work;

static struct k_timer led_timer;
static struct k_timer provisioning_timer;

static void on_light_request(uint8_t command)
{
	static uint8_t val;

	switch (command) {
	case THREAD_COAP_UTILS_LIGHT_CMD_ON:
		dk_set_led_on(LIGHT_LED);
		val = 1;
		break;

	case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
		dk_set_led_off(LIGHT_LED);
		val = 0;
		break;

	case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
		val = !val;
		dk_set_led(LIGHT_LED, val);
		break;

	default:
		break;
	}
}

static void activate_provisioning(struct k_work *item)
{
	ARG_UNUSED(item);

	ot_coap_activate_provisioning();

	k_timer_start(&led_timer, K_MSEC(100), K_MSEC(100));
	k_timer_start(&provisioning_timer, K_SECONDS(5), K_NO_WAIT);

	LOG_INF("Provisioning activated");
}

static void deactivate_provisionig(void)
{
	k_timer_stop(&led_timer);
	k_timer_stop(&provisioning_timer);

	if (ot_coap_is_provisioning_active()) {
		ot_coap_deactivate_provisioning();
		LOG_INF("Provisioning deactivated");
	}
}

static void on_provisioning_timer_expiry(struct k_timer *timer_id)
{
	ARG_UNUSED(timer_id);

	deactivate_provisionig();
}

static void on_led_timer_expiry(struct k_timer *timer_id)
{
	static uint8_t val = 1;

	ARG_UNUSED(timer_id);

	dk_set_led(PROVISIONING_LED, val);
	val = !val;
}

static void on_led_timer_stop(struct k_timer *timer_id)
{
	ARG_UNUSED(timer_id);

	dk_set_led_off(PROVISIONING_LED);
}

static void on_button_changed(uint32_t button_state, uint32_t has_changed)
{
	uint32_t buttons = button_state & has_changed;

	if (buttons & DK_BTN4_MSK) {
		k_work_submit(&provisioning_work);
	}
}
void dk_set_led_toggle(uint8_t led_idx);
static void on_thread_state_changed(uint32_t flags, void *context)
{
	struct openthread_context *ot_context = context;

	if (flags & OT_CHANGED_THREAD_ROLE) {
		switch (otThreadGetDeviceRole(ot_context->instance)) {
		case OT_DEVICE_ROLE_CHILD:
		case OT_DEVICE_ROLE_ROUTER:
		case OT_DEVICE_ROLE_LEADER:
			dk_set_led_on(OT_CONNECTION_LED);
			break;

		case OT_DEVICE_ROLE_DISABLED:
		case OT_DEVICE_ROLE_DETACHED:
		default:
			dk_set_led_off(OT_CONNECTION_LED);
			deactivate_provisionig();
			break;
		}
	}
}
struct k_thread my_thread_data;
#define MY_STACK_SIZE   (2048)
#define MY_PRIOTITY		(5)
K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE);

typedef struct BACnet_IP6_Address {
    uint8_t address[16];
    uint16_t port;
} BACNET_IP6_ADDRESS;
 static uint8_t Ttest_data[384];
static otUdpSocket sUdpSocket;
static otMessage *   ot_message;
const otMessageInfo *OTMessageInfo = NULL;
static uint8_t udp_buf[32];
static uint16_t ot_message_len = 16;
void handleUdpReceive(void *aContext, otMessage *aMessage,
                      const otMessageInfo *aMessageInfo)
{
    OT_UNUSED_VARIABLE(aContext);
    OT_UNUSED_VARIABLE(aMessage);
    OT_UNUSED_VARIABLE(aMessageInfo);
    OTMessageInfo = aMessageInfo;
    ot_message_len = otMessageGetLength(aMessage);
    otMessageRead(aMessage, 0, udp_buf, ot_message_len);
    dk_set_led_toggle(PROVISIONING_LED);
}
void initUdp(otInstance *aInstance)
{
    otSockAddr  listenSockAddr;
    memset(&sUdpSocket, 0, sizeof(sUdpSocket));
    memset(&listenSockAddr, 0, sizeof(listenSockAddr));

    listenSockAddr.mPort    = 0x1234;
    otUdpOpen(aInstance, &sUdpSocket, handleUdpReceive, aInstance);
    otUdpBind(aInstance, &sUdpSocket, &listenSockAddr, OT_NETIF_THREAD);

}

static void ot_udp_init(void)
{
    otInstance * aInstance = openthread_get_default_instance(); 
    initUdp(aInstance);
}

int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
{
    static uint32_t otFreeCount = 0;
    otError       error = OT_ERROR_NONE; 
    otMessageInfo messageInfo;
    otInstance * aInstance = openthread_get_default_instance(); 

    otMessage *   ot_message = NULL;

    otBufferInfo mesInfo;
    otMessageGetBufferInfo(aInstance, &mesInfo);

    otMessageSettings aSentting = {.mLinkSecurityEnabled = false, .mPriority = OT_MESSAGE_PRIORITY_HIGH};
    memset(&messageInfo, 0, sizeof(messageInfo));
    memcpy(&messageInfo.mPeerAddr.mFields.m8[0], &dest->address[0], 16);
    messageInfo.mPeerPort = dest->port;
    /* send the packet */
    do {
        ot_message = otUdpNewMessage(aInstance, NULL);
        if (ot_message == NULL) {
            break;
        }
        error = otMessageAppend(ot_message, mtu, mtu_len);
        if (error != OT_ERROR_NONE) {
            break;
        }
        error = otUdpSend(aInstance, &sUdpSocket, ot_message, &messageInfo);
    } while(0);

    
    if (error != OT_ERROR_NONE && ot_message != NULL)
    {
        //NRF_LOG_INFO("**OT Free:%d\n", ++otFreeCount);
        otMessageFree(ot_message);
        return 0;
    } else {
        //NRF_LOG_INFO("**OT Send:%d err:%d %x\n", ++otFreeCount, error, ot_message);
        
    }
    if (error != OT_ERROR_NONE) {
        return 0;
    }
    return mtu_len;

}
void thread_send_test(void)
{
    static uint32_t cnt = 0;
    uint8_t len = 0;
    otIp6Address  broadcastAddr;    
    BACNET_IP6_ADDRESS dest = {{0}};   
    len = sprintf(Ttest_data, "Tsend cnt:%d\n", ++cnt);
    memset(&broadcastAddr, 0x00, sizeof(broadcastAddr));
    otIp6AddressFromString("FF03::1", &broadcastAddr);
    dest.port = 0x1234;
    memcpy(&dest.address[0], &broadcastAddr.mFields.m8[0], sizeof(broadcastAddr));
    bip6_send_mpdu(&dest, Ttest_data, len);
    //DEBUG_PRINTF("Tsend cnt:%d\n", cnt);
    
}

static void ot_app(int unused1, int unused2, int unused3)
{
	ot_udp_init();
    while (1)
    {        
		thread_send_test();
		k_sleep(K_MSEC(50));
    }
}

void main(void)
{
	int ret;

	LOG_INF("Start CoAP-server sample");

	k_timer_init(&led_timer, on_led_timer_expiry, on_led_timer_stop);
	k_timer_init(&provisioning_timer, on_provisioning_timer_expiry, NULL);

	k_work_init(&provisioning_work, activate_provisioning);

	ret = ot_coap_init(&deactivate_provisionig, &on_light_request);
	if (ret) {
		LOG_ERR("Could not initialize OpenThread CoAP");
		goto end;
	}

	ret = dk_leds_init();
	if (ret) {
		LOG_ERR("Could not initialize leds, err code: %d", ret);
		goto end;
	}

	ret = dk_buttons_init(on_button_changed);
	if (ret) {
		LOG_ERR("Cannot init buttons (error: %d)", ret);
		goto end;
	}

	openthread_set_state_changed_cb(on_thread_state_changed);
	openthread_start(openthread_get_default_context());

	k_tid_t my_tid = k_thread_create(&my_thread_data, my_stack_area, K_THREAD_STACK_SIZEOF(my_stack_area), ot_app, NULL, NULL, NULL, MY_PRIOTITY, 0, K_NO_WAIT);
end:
	return;
}

Parents Reply Children
  • Hello,

    Increase the stack size for openthread by setting CONFIG_OPENTHREAD_THREAD_STACK_SIZE in your prj.conf. It is either 6240 or 3168 by default depending on whether  CONFIG_OPENTHREAD_COMMISSIONER or CONFIG_OPENTHREAD_JOINER are set or not.

    You can print the thread analyzer log in a serial terminal by including the following lines in your prj.conf:

    # Thread analyzer
    CONFIG_THREAD_ANALYZER=y
    CONFIG_THREAD_ANALYZER_USE_PRINTK=y
    CONFIG_THREAD_ANALYZER_AUTO=y
    CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=5
    CONFIG_THREAD_NAME=y

    The lines above will enable the thread analyzer to print a report regularly to the terminal.

    Best Regards,
    Maria

Related