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;
}
