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); } /** *@} **/