This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

The cc1310 node progam was hung



Hello, My TI-RTOS version  has been updated to 2.20, now I'm found new problems in the testing .Please help me analyze the reasons.

I had made some chage for two  project files of the rfwsn file :

1.The Node and Concentrator communication transceiver address changed to two byte address;2.The Concentrator sends an ACK program changed to Concentrator sends 20-byte string ,Through online debugging and observation,the node can receives 20-byte string frome the Concentrator.but the node program was hung after receives once from the Concentrator.If I don't open the Concentrator.the node can normal work.

A part  program of the Concentrator sending ACK :

static void sendPacket(uint16_t latestSourceAddress) {
uint8_t rxbuff[20]="12ABCDEFGHIJKLM33";//
uint8_t n;
    /* Set destinationAdress, but use EasyLink layers destination adress capability */
    txPacket.dstAddr[0] = latestSourceAddress;
    /* Copy ACK packet to payload, skipping the destination adress byte.
     * Note that the EasyLink API will implcitily both add the length byte and the destination address byte. */
    memcpy(txPacket.payload, &ackPacket.header, sizeof(ackPacket));
    for(n=0;n<20;n++)
     txPacket.payload[n+2]=rxbuff[n];
    txPacket.len = sizeof(ackPacket)+20;
    /* Send packet  */
    if (EasyLink_transmit(&txPacket) != EasyLink_Status_Success)
    {
        System_abort("EasyLink_transmit failed");
    }
}
If the Concentrator only send "ack Packet.header".the node program can normal running :
static void sendPacket(uint16_t latestSourceAddress) {
uint8_t rxbuff[20]="12ABCDEFGHIJKLM33";//
uint8_t n;
    /* Set destinationAdress, but use EasyLink layers destination adress capability */
    txPacket.dstAddr[0] = latestSourceAddress;
    /* Copy ACK packet to payload, skipping the destination adress byte.
     * Note that the EasyLink API will implcitily both add the length byte and the destination address byte. */
    memcpy(txPacket.payload, &ackPacket.header, sizeof(ackPacket));
//    for(n=0;n<20;n++)
//     txPacket.payload[n+2]=rxbuff[n];
    txPacket.len = sizeof(ackPacket)+20;
    /* Send packet  */
    if (EasyLink_transmit(&txPacket) != EasyLink_Status_Success)
    {
        System_abort("EasyLink_transmit failed");
    }
}
In general,the node sending program should not be affected Concentrator,  both regardless of Concentrator hair does not send ACK can not affect the node program run.
Thank you!
  • Can you send the changes you have made to ConcentratorRadioTask.c? I am struggling to understand what changes you have made, you say that the concentrator sends and Ack with 20Bytes, but the code snip show changes to the sendPacket function and not the sendAck function.

    Regards, TC.
  • Hello.Thank you for your promptly reply me.Now I post my code of ConcentratorRadioTask.c and NodeRadioTask.c:

    static uint8_t concentratorAddress; --> static uint16_t concentratorAddress;
    static void sendACK(uint8_t latestSourceAddress); --> static void sendPacket(uint16_t latestSourceAddress);
    EasyLink_enableRxAddrFilter(concentratorAddress, 1, 1); --> EasyLink_enableRxAddrFilter(concentratorAddress, 2, 1);
    struct PacketHeader { struct PacketHeader {
    uint8_t sourceAddress; --> uint16_t sourceAddress;
    uint8_t packetType; uint8_t packetType;
    }; };
    uint8_t dstAddr[8]; --> uint16_t dstAddr[8];

    EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs) -->
    EasyLink_Status EasyLink_enableRxAddrFilter(uint16_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs)

    static uint8_t addrFilterTable[EASYLINK_MAX_ADDR_FILTERS * EASYLINK_MAX_ADDR_SIZE] = {0xaa}; -->
    static uint16_t addrFilterTable[EASYLINK_MAX_ADDR_FILTERS * EASYLINK_MAX_ADDR_SIZE] ;

    uint8_t* pAddr; --> uint16_t* pAddr;
    static uint8_t addrSize = 1; --> static uint8_t addrSize = 2;

    static uint8_t nodeAddress = 0; --> static uint16_t nodeAddress = 0;
    nodeAddress = (uint8_t)TRNGNumberGet(TRNG_LOW_WORD); --> nodeAddress = (uint16_t)TRNGNumberGet(TRNG_LOW_WORD);
    EasyLink_enableRxAddrFilter(&nodeAddress, 1, 1) --> EasyLink_enableRxAddrFilter(&nodeAddress, 2, 1)
    Could you please tell me where need to change?

    Thank you!
  • It looks like you made changes to EasyLink.c/h

    user4442588 said:

    EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs) -->
    EasyLink_Status EasyLink_enableRxAddrFilter(uint16_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs)

    static uint8_t addrFilterTable[EASYLINK_MAX_ADDR_FILTERS * EASYLINK_MAX_ADDR_SIZE] = {0xaa}; -->
    static uint16_t addrFilterTable[EASYLINK_MAX_ADDR_FILTERS * EASYLINK_MAX_ADDR_SIZE] ;uint8_t* pAddr; --> uint16_t* pAddr; 
    static uint8_t addrSize = 1; --> static uint8_t addrSize = 2;


    This should not be done, the address variables and the address filter table are already dimensioned to take up to a 8B address with a uint8 array. Please revert the change in EasyLink.c/h and only make the changes to ConcentratorRadioTask.c, NodeRadioTask.c and RadioProtocol.h. To set the address size use the following call from the application:

        /* Set address Size */
        EasyLink_setCtrl(EasyLink_Ctrl_AddSize, 2);

    Also regarding the changes to RadioProtocol.h.:

    user4442588 said:
    struct PacketHeader { struct PacketHeader {
    uint8_t sourceAddress; --> uint16_t sourceAddress;
    uint8_t packetType; uint8_t packetType;
    }; };
    uint8_t dstAddr[8]; --> uint16_t dstAddr[8];

    Please ensure this is applied to both copies of RadioProtocol.h (this file is duplicated in both examples due to the way the examples are imported, in your application you may want to copy these to a common folder).

    I also noticed some other issues such as the Ack not containing the 16b address. I have applied the changes required for 16B address and tested successfully, I'll attach the .patch files showing the changes and the modified files to this post for your reference.

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/156/ConcentratorRadioTask_5F00_c.patch 

    /*
     * Copyright (c) 2015-2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form 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.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
     */
    
    /***** Includes *****/
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    #include "ConcentratorRadioTask.h"
    
    #include <ti/sysbios/BIOS.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Event.h>
    
    /* Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    
    /* Board Header files */
    #include "Board.h"
    
    #include "easylink/EasyLink.h"
    #include "RadioProtocol.h"
    
    
    /***** Defines *****/
    #define CONCENTRATORRADIO_TASK_STACK_SIZE 1024
    #define CONCENTRATORRADIO_TASK_PRIORITY   3
    
    #define RADIO_EVENT_ALL                  0xFFFFFFFF
    #define RADIO_EVENT_VALID_PACKET_RECEIVED      (uint32_t)(1 << 0)
    #define RADIO_EVENT_INVALID_PACKET_RECEIVED (uint32_t)(1 << 1)
    
    #define CONCENTRATORRADIO_MAX_RETRIES 2
    #define NORERADIO_ACK_TIMEOUT_TIME_MS (160)
    
    
    #define CONCENTRATOR_ACTIVITY_LED Board_LED0
    
    /***** Type declarations *****/
    
    
    
    /***** Variable declarations *****/
    static Task_Params concentratorRadioTaskParams;
    Task_Struct concentratorRadioTask; /* not static so you can see in ROV */
    static uint8_t concentratorRadioTaskStack[CONCENTRATORRADIO_TASK_STACK_SIZE];
    Event_Struct radioOperationEvent;  /* not static so you can see in ROV */
    static Event_Handle radioOperationEventHandle;
    
    
    
    static ConcentratorRadio_PacketReceivedCallback packetReceivedCallback;
    static union ConcentratorPacket latestRxPacket;
    static EasyLink_TxPacket txPacket;
    static struct AckPacket ackPacket;
    static uint16_t concentratorAddress;
    static int8_t latestRssi;
    
    
    /***** Prototypes *****/
    static void concentratorRadioTaskFunction(UArg arg0, UArg arg1);
    static void rxDoneCallback(EasyLink_RxPacket * rxPacket, EasyLink_Status status);
    static void notifyPacketReceived(union ConcentratorPacket* latestRxPacket);
    static void sendAck(uint16_t latestSourceAddress);
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    /* Configure LED Pin */
    PIN_Config ledPinTable[] = {
            CONCENTRATOR_ACTIVITY_LED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    void ConcentratorRadioTask_init(void) {
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, ledPinTable);
        if (!ledPinHandle)
        {
            System_abort("Error initializing board 3.3V domain pins\n");
        }
    
        /* Create event used internally for state changes */
        Event_Params eventParam;
        Event_Params_init(&eventParam);
        Event_construct(&radioOperationEvent, &eventParam);
        radioOperationEventHandle = Event_handle(&radioOperationEvent);
    
        /* Create the concentrator radio protocol task */
        Task_Params_init(&concentratorRadioTaskParams);
        concentratorRadioTaskParams.stackSize = CONCENTRATORRADIO_TASK_STACK_SIZE;
        concentratorRadioTaskParams.priority = CONCENTRATORRADIO_TASK_PRIORITY;
        concentratorRadioTaskParams.stack = &concentratorRadioTaskStack;
        Task_construct(&concentratorRadioTask, concentratorRadioTaskFunction, &concentratorRadioTaskParams, NULL);
    }
    
    void ConcentratorRadioTask_registerPacketReceivedCallback(ConcentratorRadio_PacketReceivedCallback callback) {
        packetReceivedCallback = callback;
    }
    
    static void concentratorRadioTaskFunction(UArg arg0, UArg arg1)
    {
        /* Initialize EasyLink */
        if(EasyLink_init(RADIO_EASYLINK_MODULATION) != EasyLink_Status_Success) {
            System_abort("EasyLink_init failed");
        }
    
        /* Set frequency */
        if(EasyLink_setFrequency(RADIO_FREQUENCY) != EasyLink_Status_Success) {
            System_abort("EasyLink_setFrequency failed");
        }
    
        /* Set address Size */
        EasyLink_setCtrl(EasyLink_Ctrl_AddSize, 2);
    
        /* Set concentrator address */;
        concentratorAddress = RADIO_CONCENTRATOR_ADDRESS;
        EasyLink_enableRxAddrFilter((uint8_t*) &concentratorAddress, 2, 1);
    
        /* Set up Ack packet */
        ackPacket.header.sourceAddress = concentratorAddress;
        ackPacket.header.packetType = RADIO_PACKET_TYPE_ACK_PACKET;
    
        /* Enter receive */
        if(EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success) {
            System_abort("EasyLink_receiveAsync failed");
        }
    
        while (1) {
            uint32_t events = Event_pend(radioOperationEventHandle, 0, RADIO_EVENT_ALL, BIOS_WAIT_FOREVER);
    
            /* If valid packet received */
            if(events & RADIO_EVENT_VALID_PACKET_RECEIVED) {
    
                /* Send ack packet */
                sendAck(latestRxPacket.header.sourceAddress);
    
                /* Call packet received callback */
                notifyPacketReceived(&latestRxPacket);
    
                /* Go back to RX */
                if(EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success) {
                    System_abort("EasyLink_receiveAsync failed");
                }
    
                /* toggle Activity LED */
                PIN_setOutputValue(ledPinHandle, CONCENTRATOR_ACTIVITY_LED,
                        !PIN_getOutputValue(CONCENTRATOR_ACTIVITY_LED));
            }
    
            /* If invalid packet received */
            if(events & RADIO_EVENT_INVALID_PACKET_RECEIVED) {
                /* Go back to RX */
                if(EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success) {
                    System_abort("EasyLink_receiveAsync failed");
                }
            }
        }
    }
    
    static void sendAck(uint16_t latestSourceAddress) {
    
        /* Set destinationAdress, but use EasyLink layers destination adress capability */
        txPacket.dstAddr[0] = latestSourceAddress & 0xFF;
        txPacket.dstAddr[1] |= (latestSourceAddress & 0xFF00) >> 8;
    
        /* Copy ACK packet to payload, skipping the destination adress byte.
         * Note that the EasyLink API will implcitily both add the length byte and the destination address byte. */
        memcpy(txPacket.payload, &ackPacket.header, sizeof(ackPacket));
        txPacket.len = sizeof(ackPacket);
    
        /* Send packet  */
        if (EasyLink_transmit(&txPacket) != EasyLink_Status_Success)
        {
            System_abort("EasyLink_transmit failed");
        }
    }
    
    static void notifyPacketReceived(union ConcentratorPacket* latestRxPacket)
    {
        if (packetReceivedCallback)
        {
            packetReceivedCallback(latestRxPacket, latestRssi);
        }
    }
    
    static void rxDoneCallback(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
    {
        union ConcentratorPacket* tmpRxPacket;
    
        /* If we received a packet successfully */
        if (status == EasyLink_Status_Success)
        {
            /* Save the latest RSSI, which is later sent to the receive callback */
            latestRssi = (int8_t)rxPacket->rssi;
    
            /* Check that this is a valid packet */
            tmpRxPacket = (union ConcentratorPacket*)(rxPacket->payload);
    
            /* If this is a known packet */
            if (tmpRxPacket->header.packetType == RADIO_PACKET_TYPE_ADC_SENSOR_PACKET)
            {
                /* Save packet */
                memcpy((void*)&latestRxPacket, &rxPacket->payload, sizeof(struct AdcSensorPacket));
    
                /* Signal packet received */
                Event_post(radioOperationEventHandle, RADIO_EVENT_VALID_PACKET_RECEIVED);
            }
            else if (tmpRxPacket->header.packetType == RADIO_PACKET_TYPE_DM_SENSOR_PACKET)
            {
                /* Save packet */
                memcpy((void*)&latestRxPacket, &rxPacket->payload, sizeof(struct DualModeSensorPacket));
    
                /* Signal packet received */
                Event_post(radioOperationEventHandle, RADIO_EVENT_VALID_PACKET_RECEIVED);
            }
            else
            {
                /* Signal invalid packet received */
                Event_post(radioOperationEventHandle, RADIO_EVENT_INVALID_PACKET_RECEIVED);
            }
        }
        else
        {
            /* Signal invalid packet received */
            Event_post(radioOperationEventHandle, RADIO_EVENT_INVALID_PACKET_RECEIVED);
        }
    }
    
     

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/156/ConcentratorTask_5F00_c.patch 

    /*
     * Copyright (c) 2015-2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form 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.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
     */
    
    /***** Includes *****/
    
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Event.h>
    
    /* Drivers */
    #include <ti/drivers/PIN.h>
    #include <ti/mw/display/Display.h>
    #include <ti/mw/display/DisplayExt.h>
    
    /* Board Header files */
    #include "Board.h"
    
    #include "ConcentratorRadioTask.h"
    #include "ConcentratorTask.h"
    #include "RadioProtocol.h"
    
    
    /***** Defines *****/
    #define CONCENTRATOR_TASK_STACK_SIZE 1024
    #define CONCENTRATOR_TASK_PRIORITY   3
    
    #define CONCENTRATOR_EVENT_ALL                         0xFFFFFFFF
    #define CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE    (uint32_t)(1 << 0)
    
    #define CONCENTRATOR_MAX_NODES 7
    
    #define CONCENTRATOR_DISPLAY_LINES 8
    
    /***** Type declarations *****/
    struct AdcSensorNode {
        uint16_t address;
        uint16_t latestAdcValue;
        uint8_t button;
        int8_t latestRssi;
    };
    
    
    /***** Variable declarations *****/
    static Task_Params concentratorTaskParams;
    Task_Struct concentratorTask;    /* not static so you can see in ROV */
    static uint8_t concentratorTaskStack[CONCENTRATOR_TASK_STACK_SIZE];
    Event_Struct concentratorEvent;  /* not static so you can see in ROV */
    static Event_Handle concentratorEventHandle;
    static struct AdcSensorNode latestActiveAdcSensorNode;
    struct AdcSensorNode knownSensorNodes[CONCENTRATOR_MAX_NODES];
    static struct AdcSensorNode* lastAddedSensorNode = knownSensorNodes;
    static Display_Handle hDisplayLcd;
    static Display_Handle hDisplaySerial;
    
    
    /***** Prototypes *****/
    static void concentratorTaskFunction(UArg arg0, UArg arg1);
    static void packetReceivedCallback(union ConcentratorPacket* packet, int8_t rssi);
    static void updateLcd(void);
    static void addNewNode(struct AdcSensorNode* node);
    static void updateNode(struct AdcSensorNode* node);
    static uint8_t isKnownNodeAddress(uint16_t address);
    
    
    /***** Function definitions *****/
    void ConcentratorTask_init(void) {
    
        /* Create event used internally for state changes */
        Event_Params eventParam;
        Event_Params_init(&eventParam);
        Event_construct(&concentratorEvent, &eventParam);
        concentratorEventHandle = Event_handle(&concentratorEvent);
    
        /* Create the concentrator radio protocol task */
        Task_Params_init(&concentratorTaskParams);
        concentratorTaskParams.stackSize = CONCENTRATOR_TASK_STACK_SIZE;
        concentratorTaskParams.priority = CONCENTRATOR_TASK_PRIORITY;
        concentratorTaskParams.stack = &concentratorTaskStack;
        Task_construct(&concentratorTask, concentratorTaskFunction, &concentratorTaskParams, NULL);
    }
    
    static void concentratorTaskFunction(UArg arg0, UArg arg1)
    {
        /* Initialize display and try to open both UART and LCD types of display. */
        Display_Params params;
        Display_Params_init(&params);
        params.lineClearMode = DISPLAY_CLEAR_BOTH;
    
        /* Open both an available LCD display and an UART display.
         * Whether the open call is successful depends on what is present in the
         * Display_config[] array of the board file.
         *
         * Note that for SensorTag evaluation boards combined with the SHARP96x96
         * Watch DevPack, there is a pin conflict with UART such that one must be
         * excluded, and UART is preferred by default. To display on the Watch
         * DevPack, add the precompiler define BOARD_DISPLAY_EXCLUDE_UART.
         */
        hDisplayLcd = Display_open(Display_Type_LCD, &params);
        hDisplaySerial = Display_open(Display_Type_UART, &params);
    
        /* Check if the selected Display type was found and successfully opened */
        if (hDisplaySerial)
        {
            Display_print0(hDisplaySerial, 0, 0, "Waiting for nodes...");
        }
    
        /* Check if the selected Display type was found and successfully opened */
        if (hDisplayLcd)
        {
            Display_print0(hDisplayLcd, 0, 0, "Waiting for nodes...");
        }
    
        /* Register a packet received callback with the radio task */
        ConcentratorRadioTask_registerPacketReceivedCallback(packetReceivedCallback);
    
        /* Enter main task loop */
        while(1) {
            /* Wait for event */
            uint32_t events = Event_pend(concentratorEventHandle, 0, CONCENTRATOR_EVENT_ALL, BIOS_WAIT_FOREVER);
    
            /* If we got a new ADC sensor value */
            if(events & CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE) {
                /* If we knew this node from before, update the value */
                if(isKnownNodeAddress(latestActiveAdcSensorNode.address)) {
                    updateNode(&latestActiveAdcSensorNode);
                }
                else {
                    /* Else add it */
                    addNewNode(&latestActiveAdcSensorNode);
                }
    
                /* Update the values on the LCD */
                updateLcd();
            }
        }
    }
    
    static void packetReceivedCallback(union ConcentratorPacket* packet, int8_t rssi)
    {
        /* If we recived an ADC sensor packet, for backward compatibility */
        if (packet->header.packetType == RADIO_PACKET_TYPE_ADC_SENSOR_PACKET)
        {
            /* Save the values */
            latestActiveAdcSensorNode.address = packet->header.sourceAddress;
            latestActiveAdcSensorNode.latestAdcValue = packet->adcSensorPacket.adcValue;
            latestActiveAdcSensorNode.button = 0; //no button value in ADC packet
            latestActiveAdcSensorNode.latestRssi = rssi;
    
            Event_post(concentratorEventHandle, CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE);
        }
        /* If we recived an DualMode ADC sensor packet*/
        else if(packet->header.packetType == RADIO_PACKET_TYPE_DM_SENSOR_PACKET)
        {
    
            /* Save the values */
            latestActiveAdcSensorNode.address = packet->header.sourceAddress;
            latestActiveAdcSensorNode.latestAdcValue = packet->dmSensorPacket.adcValue;
            latestActiveAdcSensorNode.button = packet->dmSensorPacket.button;
            latestActiveAdcSensorNode.latestRssi = rssi;
    
            Event_post(concentratorEventHandle, CONCENTRATOR_EVENT_NEW_ADC_SENSOR_VALUE);
        }
    }
    
    static uint8_t isKnownNodeAddress(uint16_t address) {
        uint8_t found = 0;
        uint8_t i;
        for (i = 0; i < CONCENTRATOR_MAX_NODES; i++)
        {
            if (knownSensorNodes[i].address == address)
            {
                found = 1;
                break;
            }
        }
        return found;
    }
    
    static void updateNode(struct AdcSensorNode* node) {
        uint8_t i;
        for (i = 0; i < CONCENTRATOR_MAX_NODES; i++) {
            if (knownSensorNodes[i].address == node->address)
            {
                knownSensorNodes[i].latestAdcValue = node->latestAdcValue;
                knownSensorNodes[i].latestRssi = node->latestRssi;
                knownSensorNodes[i].button = node->button;
                break;
            }
        }
    }
    
    static void addNewNode(struct AdcSensorNode* node) {
        *lastAddedSensorNode = *node;
    
        /* Increment and wrap */
        lastAddedSensorNode++;
        if (lastAddedSensorNode > &knownSensorNodes[CONCENTRATOR_MAX_NODES-1])
        {
            lastAddedSensorNode = knownSensorNodes;
        }
    }
    
    static void updateLcd(void) {
        struct AdcSensorNode* nodePointer = knownSensorNodes;
        uint8_t currentLcdLine;
    
        /* Clear the display and write header on first line */
        Display_clear(hDisplayLcd);
        Display_print0(hDisplayLcd, 0, 0, "Nodes Value SW  RSSI");
    
        //clear screen, put cuser to beggining of terminal and print the header
        Display_print0(hDisplaySerial, 0, 0, "\033[2J \033[0;0HNodes   Value   SW    RSSI");
    
        /* Start on the second line */
        currentLcdLine = 1;
    
        /* Write one line per node */
        while ((nodePointer < &knownSensorNodes[CONCENTRATOR_MAX_NODES]) &&
              (nodePointer->address != 0) &&
              (currentLcdLine < CONCENTRATOR_DISPLAY_LINES))
        {
            /* print to LCD */
            Display_print4(hDisplayLcd, currentLcdLine, 0, "0x%04x  %04d  %d   %04d",
                    nodePointer->address, nodePointer->latestAdcValue, nodePointer->button,
                    nodePointer->latestRssi);
    
            /* print to UART */
            Display_print4(hDisplaySerial, 0, 0, "0x%02x    %04d    %d    %04d",
                    nodePointer->address, nodePointer->latestAdcValue, nodePointer->button,
                    nodePointer->latestRssi);
    
            nodePointer++;
            currentLcdLine++;
        }
    }
    
     

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/156/RadioProtocol_5F00_h.patch 

    RadioProtocol.h 

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/156/NodeRadioTask_5F00_c.patch 

    /*
     * Copyright (c) 2015-2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form 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.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
     */
    
    /***** Includes *****/
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    
    /* Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    
    /* Board Header files */
    #include "Board.h"
    
    #include <stdlib.h>
    #include <driverlib/trng.h>
    #include <driverlib/aon_batmon.h>
    #include "easylink/EasyLink.h"
    #include "RadioProtocol.h"
    #include "NodeRadioTask.h"
    
    
    /***** Defines *****/
    #define NODERADIO_TASK_STACK_SIZE 1024
    #define NODERADIO_TASK_PRIORITY   3
    
    #define RADIO_EVENT_ALL                 0xFFFFFFFF
    #define RADIO_EVENT_SEND_ADC_DATA       (uint32_t)(1 << 0)
    #define RADIO_EVENT_DATA_ACK_RECEIVED   (uint32_t)(1 << 1)
    #define RADIO_EVENT_ACK_TIMEOUT         (uint32_t)(1 << 2)
    #define RADIO_EVENT_SEND_FAIL           (uint32_t)(1 << 3)
    
    #define NODERADIO_MAX_RETRIES 2
    #define NORERADIO_ACK_TIMEOUT_TIME_MS (160)
    
    
    /***** Type declarations *****/
    struct RadioOperation {
        EasyLink_TxPacket easyLinkTxPacket;
        uint8_t retriesDone;
        uint8_t maxNumberOfRetries;
        uint32_t ackTimeoutMs;
        enum NodeRadioOperationStatus result;
    };
    
    
    /***** Variable declarations *****/
    static Task_Params nodeRadioTaskParams;
    Task_Struct nodeRadioTask;        /* not static so you can see in ROV */
    static uint8_t nodeRadioTaskStack[NODERADIO_TASK_STACK_SIZE];
    Semaphore_Struct radioAccessSem;  /* not static so you can see in ROV */
    static Semaphore_Handle radioAccessSemHandle;
    Event_Struct radioOperationEvent; /* not static so you can see in ROV */
    static Event_Handle radioOperationEventHandle;
    Semaphore_Struct radioResultSem;  /* not static so you can see in ROV */
    static Semaphore_Handle radioResultSemHandle;
    static struct RadioOperation currentRadioOperation;
    static uint16_t adcData;
    static uint16_t nodeAddress = 0;
    static struct DualModeSensorPacket dmSensorPacket;
    
    
    /* previous Tick count used to calculate uptime for the Sub1G packet */
    static uint32_t prevTicks;
    
    /* Pin driver handle */
    extern PIN_Handle ledPinHandle;
    
    /***** Prototypes *****/
    static void nodeRadioTaskFunction(UArg arg0, UArg arg1);
    static void returnRadioOperationStatus(enum NodeRadioOperationStatus status);
    static void sendDmPacket(struct DualModeSensorPacket sensorPacket, uint8_t maxNumberOfRetries, uint32_t ackTimeoutMs);
    static void resendPacket();
    static void rxDoneCallback(EasyLink_RxPacket * rxPacket, EasyLink_Status status);
    
    /***** Function definitions *****/
    void NodeRadioTask_init(void) {
    
        /* Create semaphore used for exclusive radio access */
        Semaphore_Params semParam;
        Semaphore_Params_init(&semParam);
        Semaphore_construct(&radioAccessSem, 1, &semParam);
        radioAccessSemHandle = Semaphore_handle(&radioAccessSem);
    
        /* Create semaphore used for callers to wait for result */
        Semaphore_construct(&radioResultSem, 0, &semParam);
        radioResultSemHandle = Semaphore_handle(&radioResultSem);
    
        /* Create event used internally for state changes */
        Event_Params eventParam;
        Event_Params_init(&eventParam);
        Event_construct(&radioOperationEvent, &eventParam);
        radioOperationEventHandle = Event_handle(&radioOperationEvent);
    
        /* Create the radio protocol task */
        Task_Params_init(&nodeRadioTaskParams);
        nodeRadioTaskParams.stackSize = NODERADIO_TASK_STACK_SIZE;
        nodeRadioTaskParams.priority = NODERADIO_TASK_PRIORITY;
        nodeRadioTaskParams.stack = &nodeRadioTaskStack;
        Task_construct(&nodeRadioTask, nodeRadioTaskFunction, &nodeRadioTaskParams, NULL);
    }
    
    static void nodeRadioTaskFunction(UArg arg0, UArg arg1)
    {
        /* Initialize EasyLink */
        if(EasyLink_init(RADIO_EASYLINK_MODULATION) != EasyLink_Status_Success) {
            System_abort("EasyLink_init failed");
        }
    
        /* Set frequency */
        if(EasyLink_setFrequency(RADIO_FREQUENCY) != EasyLink_Status_Success) {
            System_abort("EasyLink_setFrequency failed");
        }
    
        /* Set address Size */
        EasyLink_setCtrl(EasyLink_Ctrl_AddSize, 2);
    
        /* Use the True Random Number Generator to generate sensor node address randomly */;
        Power_setDependency(PowerCC26XX_PERIPH_TRNG);
        TRNGEnable();
        /* Do not accept the same address as the concentrator, in that case get a new random value */
        do
        {
            while (!(TRNGStatusGet() & TRNG_NUMBER_READY))
            {
                //wiat for randum number generator
            }
            nodeAddress = (uint8_t)TRNGNumberGet(TRNG_LOW_WORD);
            //hard code the high byte so we can test its working
            nodeAddress |= 0xAA00;
        } while (nodeAddress == RADIO_CONCENTRATOR_ADDRESS);
        TRNGDisable();
        Power_releaseDependency(PowerCC26XX_PERIPH_TRNG);
    
        /* Set the filter to the generated random address */
        if (EasyLink_enableRxAddrFilter((uint8_t*) &nodeAddress, 2, 1) != EasyLink_Status_Success)
        {
            System_abort("EasyLink_enableRxAddrFilter failed");
        }
    
        /* Setup ADC sensor packet */
        dmSensorPacket.header.sourceAddress = nodeAddress;
        dmSensorPacket.header.packetType = RADIO_PACKET_TYPE_DM_SENSOR_PACKET;
    
    
        /* Initialise previous Tick count used to calculate uptime for the TLM beacon */
        prevTicks = Clock_getTicks();
    
        /* Enter main task loop */
        while (1)
        {
            /* Wait for an event */
            uint32_t events = Event_pend(radioOperationEventHandle, 0, RADIO_EVENT_ALL, BIOS_WAIT_FOREVER);
    
            /* If we should send ADC data */
            if (events & RADIO_EVENT_SEND_ADC_DATA)
            {
                uint32_t currentTicks;
    
                currentTicks = Clock_getTicks();
                //check for wrap around
                if (currentTicks > prevTicks)
                {
                    //calculate time since last reading in 0.1s units
                    dmSensorPacket.time100MiliSec += ((currentTicks - prevTicks) * Clock_tickPeriod) / 100000;
                }
                else
                {
                    //calculate time since last reading in 0.1s units
                    dmSensorPacket.time100MiliSec += ((prevTicks - currentTicks) * Clock_tickPeriod) / 100000;
                }
                prevTicks = currentTicks;
    
                dmSensorPacket.batt = AONBatMonBatteryVoltageGet();
                dmSensorPacket.adcValue = adcData;
                dmSensorPacket.button = !PIN_getInputValue(Board_BUTTON0);
    
    
                sendDmPacket(dmSensorPacket, NODERADIO_MAX_RETRIES, NORERADIO_ACK_TIMEOUT_TIME_MS);
            }
    
            /* If we get an ACK from the concentrator */
            if (events & RADIO_EVENT_DATA_ACK_RECEIVED)
            {
                returnRadioOperationStatus(NodeRadioStatus_Success);
            }
    
            /* If we get an ACK timeout */
            if (events & RADIO_EVENT_ACK_TIMEOUT)
            {
    
                /* If we haven't resent it the maximum number of times yet, then resend packet */
                if (currentRadioOperation.retriesDone < currentRadioOperation.maxNumberOfRetries)
                {
                    resendPacket();
                }
                else
                {
                    /* Else return send fail */
                    Event_post(radioOperationEventHandle, RADIO_EVENT_SEND_FAIL);
                }
            }
    
            /* If send fail */
            if (events & RADIO_EVENT_SEND_FAIL)
            {
                returnRadioOperationStatus(NodeRadioStatus_Failed);
            }
    
        }
    }
    
    enum NodeRadioOperationStatus NodeRadioTask_sendAdcData(uint16_t data)
    {
        enum NodeRadioOperationStatus status;
    
        /* Get radio access sempahore */
        Semaphore_pend(radioAccessSemHandle, BIOS_WAIT_FOREVER);
    
        /* Save data to send */
        adcData = data;
    
        /* Raise RADIO_EVENT_SEND_ADC_DATA event */
        Event_post(radioOperationEventHandle, RADIO_EVENT_SEND_ADC_DATA);
    
        /* Wait for result */
        Semaphore_pend(radioResultSemHandle, BIOS_WAIT_FOREVER);
    
        /* Get result */
        status = currentRadioOperation.result;
    
        /* Return radio access semaphore */
        Semaphore_post(radioAccessSemHandle);
    
        return status;
    }
    
    static void returnRadioOperationStatus(enum NodeRadioOperationStatus result)
    {
        /* Save result */
        currentRadioOperation.result = result;
    
        /* Post result semaphore */
        Semaphore_post(radioResultSemHandle);
    }
    
    static void sendDmPacket(struct DualModeSensorPacket sensorPacket, uint8_t maxNumberOfRetries, uint32_t ackTimeoutMs)
    {
        /* Set destination address in EasyLink API */
        currentRadioOperation.easyLinkTxPacket.dstAddr[0] = RADIO_CONCENTRATOR_ADDRESS;
    
        /* Copy ADC packet to payload
         * Note that the EasyLink API will implcitily both add the length byte and the destination address byte. */
        memcpy(currentRadioOperation.easyLinkTxPacket.payload, ((uint8_t*)&dmSensorPacket), sizeof(struct DualModeSensorPacket));
        currentRadioOperation.easyLinkTxPacket.len = sizeof(struct DualModeSensorPacket);
    
        /* Setup retries */
        currentRadioOperation.maxNumberOfRetries = maxNumberOfRetries;
        currentRadioOperation.ackTimeoutMs = ackTimeoutMs;
        currentRadioOperation.retriesDone = 0;
        EasyLink_setCtrl(EasyLink_Ctrl_AsyncRx_TimeOut, EasyLink_ms_To_RadioTime(ackTimeoutMs));
    
        /* Send packet  */
        if (EasyLink_transmit(&currentRadioOperation.easyLinkTxPacket) != EasyLink_Status_Success)
        {
            System_abort("EasyLink_transmit failed");
        }
    
        /* Enter RX */
        if (EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success)
        {
            System_abort("EasyLink_receiveAsync failed");
        }
    }
    
    static void resendPacket()
    {
        /* Send packet  */
        if (EasyLink_transmit(&currentRadioOperation.easyLinkTxPacket) != EasyLink_Status_Success)
        {
            System_abort("EasyLink_transmit failed");
        }
    
        /* Enter RX and wait for ACK with timeout */
        if (EasyLink_receiveAsync(rxDoneCallback, 0) != EasyLink_Status_Success)
        {
            System_abort("EasyLink_receiveAsync failed");
        }
    
        /* Increase retries by one */
        currentRadioOperation.retriesDone++;
    }
    
    static void rxDoneCallback(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
    {
        struct PacketHeader* packetHeader;
    
        /* If this callback is called because of a packet received */
        if (status == EasyLink_Status_Success)
        {
            /* Check the payload header */
            packetHeader = (struct PacketHeader*)rxPacket->payload;
    
            /* Check if this is an ACK packet */
            if (packetHeader->packetType == RADIO_PACKET_TYPE_ACK_PACKET)
            {
                /* Signal ACK packet received */
                Event_post(radioOperationEventHandle, RADIO_EVENT_DATA_ACK_RECEIVED);
            }
        }
        /* did the Rx timeout */
        else if(status == EasyLink_Status_Rx_Timeout)
        {
            /* Post a RADIO_EVENT_ACK_TIMEOUT event */
            Event_post(radioOperationEventHandle, RADIO_EVENT_ACK_TIMEOUT);
        }
    
    }
    

    Remember to copy RadioProtocol.h to both projects.

    Regards, TC.

  • Thank you!
    If the Concentrator call sendACK () function to send 20-Byte string,and the node receives it .the node progam can be hung.Could you tests it?