NRF52840:The thread Data sending and receiving is disconnected

Hi Nordic Team: 

I use this example "freertos_coap_server", when the communication is abnormal, the network communication can be restored only after power failure and restart. Based on this example, I

changed the transmission protocol to udp. main.c is the only file I changed.This makes it easy to repeat the problem of abnormal test communication.I really hope to get your help.Thank you. 

OS: Windows 10, IDE: Segger Embedded Studio for ARM 5.32, HW: NRF52840 DK   

Segger project file is in   examples\thread\freertos_coap_server\pca10056\blank\ses   

NRF5_SDK_version:V4.2.0     

/**
 * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 *
 * @defgroup freertos_coap_server_example_main main.c
 * @{
 * @ingroup freertos_coap_server_example
 *
 * @brief Thread CoAP server example with FreeRTOS Application main file.
 *
 * This file contains the source code for a sample application using Thread CoAP server and FreeRTOS.
 *
 */
#include "FreeRTOS.h"
#include "nrf_drv_clock.h"
#include "task.h"

#define NRF_LOG_MODULE_NAME APP
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
NRF_LOG_MODULE_REGISTER();

#include "app_timer.h"
#include "bsp_thread.h"
#include "thread_coap_utils.h"
#include "thread_utils.h"

#include <openthread/instance.h>
#include <openthread/thread.h>

#define THREAD_STACK_TASK_STACK_SIZE     (( 1024 * 8 ) / sizeof(StackType_t))   /**< FreeRTOS task stack size is determined in multiples of StackType_t. */
#define LOG_TASK_STACK_SIZE              ( 1024 / sizeof(StackType_t))          /**< FreeRTOS task stack size is determined in multiples of StackType_t. */
#define THREAD_STACK_TASK_PRIORITY       2
#define LOG_TASK_PRIORITY                1
#define LED1_TASK_PRIORITY               1
#define LED2_TASK_PRIORITY               1
#define LED1_BLINK_INTERVAL              427
#define LED2_BLINK_INTERVAL              472
#define LOG_TASK_INTERVAL                100

typedef struct
{
    TaskHandle_t thread_stack_task;   /**< Thread stack task handle */
    TaskHandle_t led1_task;           /**< LED1 task handle*/
    TaskHandle_t led2_task;           /**< LED2 task handle*/
    TaskHandle_t ot_app;
#if NRF_LOG_ENABLED
    TaskHandle_t logger_task;         /**< Definition of Logger thread. */
#endif
} application_t;

application_t m_app =
{
    .thread_stack_task = NULL,
    .led1_task         = NULL,
    .led2_task         = NULL,
    .ot_app         = NULL,
#if NRF_LOG_ENABLED
    .logger_task       = NULL,
#endif
};

/***************************************************************************************************
 * @section CoAP
 **************************************************************************************************/

static inline void light_on(void)
{
    vTaskResume(m_app.led1_task);
    vTaskResume(m_app.led2_task);
}


static inline void light_off(void)
{
    vTaskSuspend(m_app.led1_task);
    LEDS_OFF(BSP_LED_2_MASK);

    vTaskSuspend(m_app.led2_task);
    LEDS_OFF(BSP_LED_3_MASK);
}


static inline void light_toggle(void)
{
    if (!thread_coap_utils_light_is_led_blinking())
    {
        light_on();
    }
    else
    {
        light_off();
    }
}


static void on_light_change(thread_coap_utils_light_command_t command)
{
    switch (command)
    {
        case THREAD_COAP_UTILS_LIGHT_CMD_ON:
            light_on();
            break;

        case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
            light_off();
            break;

        case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
            light_toggle();
            break;

        default:
            ASSERT(false);
            break;
    }
}

/***************************************************************************************************
 * @section Signal handling
 **************************************************************************************************/

void otTaskletsSignalPending(otInstance * p_instance)
{
    if (m_app.thread_stack_task == NULL)
    {
        return;
    }

    UNUSED_RETURN_VALUE(xTaskNotifyGive(m_app.thread_stack_task));
}


void otSysEventSignalPending(void)
{
    static BaseType_t xHigherPriorityTaskWoken;

    if (m_app.thread_stack_task == NULL)
    {
        return;
    }

    vTaskNotifyGiveFromISR(m_app.thread_stack_task, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

/***************************************************************************************************
 * @section State change handling
 **************************************************************************************************/

 static void thread_state_changed_callback(uint32_t flags, void * p_context)
{
    if (flags & OT_CHANGED_THREAD_ROLE)
    {
        switch(otThreadGetDeviceRole(p_context))
        {
            case OT_DEVICE_ROLE_CHILD:
            case OT_DEVICE_ROLE_ROUTER:
            case OT_DEVICE_ROLE_LEADER:
                break;

            case OT_DEVICE_ROLE_DISABLED:
            case OT_DEVICE_ROLE_DETACHED:
            default:
                thread_coap_utils_provisioning_enable_set(false);
                break;
        }
    }

    NRF_LOG_INFO("State changed! Flags: 0x%08x Current role: %d\r\n", flags, otThreadGetDeviceRole(p_context));
}

/***************************************************************************************************
 * @section Buttons
 **************************************************************************************************/

static void bsp_event_handler(bsp_event_t event)
{
    switch (event)
    {
        case BSP_EVENT_KEY_3:
            thread_coap_utils_provisioning_enable_set(true);
            break;

        default:
            return;
    }
}

/***************************************************************************************************
 * @section Initialization
 **************************************************************************************************/

 /**@brief Function for initializing the Application Timer Module
 */
static void timer_init(void)
{
    uint32_t error_code = app_timer_init();
    APP_ERROR_CHECK(error_code);
}


/**@brief Function for initializing the Thread Board Support Package
 */
static void thread_bsp_init(void)
{
    uint32_t error_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
    APP_ERROR_CHECK(error_code);

    error_code = bsp_thread_init(thread_ot_instance_get());
    APP_ERROR_CHECK(error_code);
}


/**@brief Function for initializing the Thread Stack
 */
static void thread_instance_init(void)
{
    thread_configuration_t thread_configuration =
    {
        .radio_mode        = THREAD_RADIO_MODE_RX_ON_WHEN_IDLE,
        .autocommissioning = true,
    };

    thread_init(&thread_configuration);
    //thread_cli_init();
    thread_state_changed_callback_set(thread_state_changed_callback);
}


/**@brief Function for initializing the Constrained Application Protocol Module
 */
static void thread_coap_init(void)
{
    thread_coap_utils_configuration_t thread_coap_configuration =
    {
        .coap_server_enabled               = true,
        .coap_client_enabled               = false,
        .configurable_led_blinking_enabled = true,
    };

    thread_coap_utils_init(&thread_coap_configuration);
}


/**@brief Function for initializing the nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}


/**@brief Function for initializing the clock.
 */
static void clock_init(void)
{
    ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
}


static void thread_stack_task(void * arg)
{
    UNUSED_PARAMETER(arg);

    while (1)
    {
        thread_process();
        UNUSED_RETURN_VALUE(ulTaskNotifyTake(pdTRUE, portMAX_DELAY));
    }
}

/***************************************************************************************************
 * @section Leds
 **************************************************************************************************/

static void led1_task(void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);

    while (1)
    {
        LEDS_INVERT(BSP_LED_2_MASK);
        vTaskDelay(LED1_BLINK_INTERVAL);
    }
}


static void led2_task(void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);

    while (1)
    {
        LEDS_INVERT(BSP_LED_3_MASK);
        vTaskDelay(LED2_BLINK_INTERVAL);
    }
}

#if NRF_LOG_ENABLED
static void logger_thread(void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);

    while (true)
    {
        if (!(NRF_LOG_PROCESS()))
        {
            /* No more logs, let's sleep and wait for any */
            //thread_coap_utils_multicast_light_request_send2(0, 1);
            vTaskDelay(LOG_TASK_INTERVAL);
        }
    }
}
#endif //NRF_LOG_ENABLED

/***************************************************************************************************
 * @section Main
 **************************************************************************************************/
#include <openthread/message.h>
#include <openthread/udp.h>
#include <openthread/ip6.h>
#include <openthread/link.h>
typedef struct BACnet_IP6_Address {
    uint8_t address[16];
    uint16_t port;
} BACNET_IP6_ADDRESS;
 /*UDP*/
 static uint8_t Ttest_data[384];
 /* Set Extended Pan ID to DEAD00BEEF00CAFE */
static const uint8_t thread_extPanId[OT_EXT_PAN_ID_SIZE] = {0xDE, 0xAD, 0x00, 0xBE, 0xEF, 0x00, 0xCA, 0xFE};//dafult
/* Set network key to 00112233445566778899aabbccddeeff */
static const uint8_t thread_network_key[OT_MASTER_KEY_SIZE] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
/*broadcast addr */
static const char UDP_DEST_ADDR[] = "ff03::1";
static otUdpSocket sUdpSocket;
static otMessage *   ot_message;
const otMessageInfo *OTMessageInfo = NULL;
static uint8_t udp_buf[384];
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);
    nrf_gpio_pin_toggle(LED_1);
}
otError       udp_error = OT_ERROR_GENERIC;
void initUdp(otInstance *aInstance)
{
    otSockAddr  listenSockAddr;
    otError       error = OT_ERROR_NONE;
    memset(&sUdpSocket, 0, sizeof(sUdpSocket));
    memset(&listenSockAddr, 0, sizeof(listenSockAddr));

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

}

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

otError setNetworkConfiguration(void)
{
    static char          aNetworkName[16] = {0};
    otOperationalDataset aDataset;
    const otExtAddress *ot_Extaddr;
    otInstance * aInstance = thread_ot_instance_get(); 
    
    memset(&aDataset, 0, sizeof(otOperationalDataset));
    memset(aNetworkName, 0x00, sizeof(aNetworkName));

    ot_Extaddr = otLinkGetExtendedAddress(aInstance);
    /*
     * Fields that can be configured in otOperationDataset to override defaults:
     *     Network Name, Mesh Local Prefix, Extended PAN ID, PAN ID, Delay Timer,
     *     Channel, Channel Mask Page 0, Network Key, PSKc, Security Policy
     */
    aDataset.mActiveTimestamp                      = 1;
    aDataset.mComponents.mIsActiveTimestampPresent = true;

    /* Set Channel to 15 */
    aDataset.mChannel                      = 11;
    aDataset.mComponents.mIsChannelPresent = true;

    /* Set Pan ID to 2222 */
    aDataset.mPanId                      = (otPanId)0xabcc;
    aDataset.mComponents.mIsPanIdPresent = true;

    /* Set Extended Pan ID to C0DE1AB5C0DE1AB5 */
    memcpy(aDataset.mExtendedPanId.m8, thread_extPanId, sizeof(aDataset.mExtendedPanId));
    aDataset.mComponents.mIsExtendedPanIdPresent = true;

    /* Set network key to 1234C0DE1AB51234C0DE1AB51234C0DE */
    memcpy(aDataset.mMasterKey.m8, thread_network_key, sizeof(aDataset.mMasterKey));
    aDataset.mComponents.mIsMasterKeyPresent = true;

    /* Set Network Name to OTCodelab */
    //size_t length = strlen(aNetworkName);
    size_t length = sprintf(aNetworkName, "%s-%02x%02x", "WNGTTEST", ot_Extaddr->m8[6], ot_Extaddr->m8[7]);
    ASSERT(length <= OT_NETWORK_NAME_MAX_SIZE);
    memcpy(aDataset.mNetworkName.m8, aNetworkName, length);
    aDataset.mComponents.mIsNetworkNamePresent = true;

    /* Set the router selection jitter to override the 2 minute default.
       CLI cmd > routerselectionjitter 20
       Warning: For demo purposes only - not to be used in a real product */
//    uint8_t jitterValue = 100;
//    otThreadSetRouterSelectionJitter(aInstance, jitterValue);
    return otDatasetSetActive(aInstance, &aDataset);
}

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 = thread_ot_instance_get(); 

    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;
        }
        CRITICAL_REGION_ENTER();
        error = otUdpSend(&sUdpSocket, ot_message, &messageInfo);
        CRITICAL_REGION_EXIT();
    } 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(void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);
    static bool flag = true;
    while (1)
    {
        thread_send_test();
        vTaskDelay(50);
    }
}

int main(void)
{
    log_init();
    clock_init();
    timer_init();

    thread_instance_init();

    //thread_coap_init();
    thread_bsp_init();
    //thread_coap_utils_light_command_handler_set(on_light_change);
    ot_udp_init();
    NRF_LOG_INFO("APP\n");
    // Start thread stack execution.
    if (pdPASS != xTaskCreate(thread_stack_task, "THR", THREAD_STACK_TASK_STACK_SIZE, NULL, THREAD_STACK_TASK_PRIORITY, &m_app.thread_stack_task))
    {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }

    // Start execution.
    //if (pdPASS != xTaskCreate(led1_task, "LED1", configMINIMAL_STACK_SIZE, NULL, LED1_TASK_PRIORITY, &m_app.led1_task))
    //{
    //    APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    //}

    //// Start execution.
    //if (pdPASS != xTaskCreate(led2_task, "LED2", configMINIMAL_STACK_SIZE, NULL, LED2_TASK_PRIORITY, &m_app.led2_task))
    //{
    //    APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    //}

#if NRF_LOG_ENABLED
    // Start execution.
    if (pdPASS != xTaskCreate(logger_thread, "LOGGER", LOG_TASK_STACK_SIZE, NULL, LOG_TASK_PRIORITY, &m_app.logger_task))
    {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }
#endif

    // Start execution.
    if (pdPASS != xTaskCreate(ot_app, "OTAPP", THREAD_STACK_TASK_STACK_SIZE, NULL, LED2_TASK_PRIORITY, &m_app.led2_task))
    {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }
    /* Start FreeRTOS scheduler. */
    vTaskStartScheduler();

    while (true)
    {
        /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
         * in vTaskStartScheduler function. */
    }
}

void HardFault_Handler(void)
{
    //xTaskStackShowCurrentTask();
    NVIC_SystemReset();
    while(1);
}

/**
 *@}
 **/

Related