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.

Compiler/CC2650: Problem using osal_snv_init() when receiving a packet

Part Number: CC2650
Other Parts Discussed in Thread: SYSBIOS,

Tool/software: TI C/C++ Compiler

Hello,

I'm using ccs2650 launchpad to receive a packet from another device using smartRF studio 7 and save this packet in NV area by using osal_write and read and show it using UART

but the Problem is using osal_snv_init() which will cause a problem and when I delete it I'm able to receive normally but I can't save the packet ,I don't know what is the relation between using osal_snv_init() and receiving the packet The error message is: Failed to remove the debug state from the target before disconnecting.  There may still be breakpoint op-codes embedded in program memory.  It is recommended that you reset the emulator before you connect and reload your program before you continue debuggi

my code is:

#include <stdio.h>
#include <stdlib.h>
// XDCtools Header files
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/cfg/global.h>

// BIOS Header files
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>


#include <ti/drivers/UART.h>


#include "Board.h"

#include <stdint.h>
#include "hal_types.h"
#include "comdef.h"
#include <hal_flash.h>
#include <osal.h>
#include <osal_snv.h>
#include <driverlib/vims.h>
#include <driverlib/aon_batmon.h>


#include <hal_defs.h>
#include <hal_assert.h>


#include <ti/drivers/rf/RF.h>
#include <ti/drivers/PIN.h>
#include <driverlib/rf_prop_mailbox.h>
#include "RFQueue.h"
#include "smartrf_settings/smartrf_settings.h"

#define TS     1024

Task_Struct task0Struct;
static uint8_t task0Stack[TS];
#define TASK_PRIORITY   2


#define DATA_ENTRY_HEADER_SIZE 8  /* Constant header size of a Generic Data Entry */
#define MAX_LENGTH             30 /* Max length byte the radio will accept */
#define NUM_DATA_ENTRIES       2  /* NOTE: Only two data entries supported at the moment */
#define NUM_APPENDED_BYTES     2  /* The Data Entries data field will contain:
                                   * 1 Header byte (RF_cmdPropRx.rxConf.bIncludeHdr = 0x1)
                                   * Max 30 payload bytes
                                   * 1 status byte (RF_cmdPropRx.rxConf.bAppendStatus = 0x1) */

static void ReciveThePacket(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
static RF_Object rfObject;
static RF_Handle rfHandle;

/* Buffer which contains all Data Entries for receiving data.
 * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
#if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
        static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                                 MAX_LENGTH,
                                                                 NUM_APPENDED_BYTES)];
#elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
        static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                                 MAX_LENGTH,
                                                                 NUM_APPENDED_BYTES)];
#elif defined(__GNUC__)
        static uint8_t rxDataEntryBuffer [RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
            MAX_LENGTH, NUM_APPENDED_BYTES)] __attribute__ ((aligned (4)));
#else
    #error This compiler is not supported.
#endif

/* Receive dataQueue for RF Core to fill in data */
static dataQueue_t dataQueue;
static rfc_dataEntryGeneral_t* currentDataEntry;
static uint8_t packetLength;
static uint8_t* packetDataPointer;



static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */

uint8 * MemBuffWrite ;
uint8 * MemBuffRead ;




int i;


uint8 status = SUCCESS;

void ReciveThePacket(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{

    UART_Handle uart;
    UART_Params uartParams;
    // Create a UART with data processing off.
    UART_Params_init(&uartParams);  //Function to initialize the UART_Params struct to its defaults
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
    uart = UART_open(Board_UART0, &uartParams); //Function to initialize a given UART peripheral
   uint8 FlashAdrr= 0x80;   // the address for NV is form 0x80 to 0x8F
    uint8 AuxVar[30];

    memset (AuxVar, '\0', sizeof(AuxVar));

    MemBuffRead= (uint8*)malloc (30*sizeof(uint8));
    MemBuffWrite = (uint8*)malloc (30*sizeof(uint8));



    osal_snv_init();
    if (e & RF_EventRxEntryDone)
    {
 for (i=1;i<6;i++)
 {

        /* Get current unhandled data entry */
        currentDataEntry = RFQueue_getDataEntry();

        /* Handle the packet data, located at &currentDataEntry->data:
         * - Length is the first byte with the current configuration
         * - Data starts from the second byte */
        packetLength      = *(uint8_t*)(&currentDataEntry->data);
        packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);

        /* Copy the payload + the status byte to the packet variable */
        memcpy(packet, packetDataPointer, (packetLength + 1));
        strcpy (MemBuffWrite,packet);

        status =  osal_snv_write(FlashAdrr, 10, MemBuffWrite );
        status = osal_snv_read( FlashAdrr, 10, MemBuffRead);
        strcpy (AuxVar,MemBuffRead);
        System_printf("The packet is successfully received and it its number: %d",i);
        System_flush();
        System_printf("   The Address of the packet in SV is  %x",FlashAdrr);
        System_flush();
        System_printf("   The packet is %s%x",AuxVar,AuxVar);
        System_flush();*/


       UART_write(uart, AuxVar, sizeof(AuxVar));
        FlashAdrr++;

        free(MemBuffWrite); //free address MemBuffWrite
        free(MemBuffRead); //free address MemBuffRead */
        RFQueue_nextEntry();

        }
    }
}

Void Taskfunction (UArg arg0, UArg arg1)
{

    RF_Params rfParams;
    RF_Params_init(&rfParams);

    if( RFQueue_defineQueue(&dataQueue,rxDataEntryBuffer, sizeof(rxDataEntryBuffer), NUM_DATA_ENTRIES, MAX_LENGTH + NUM_APPENDED_BYTES))
    {
        /* Failed to allocate space for all data entries */
        while(1);
    }

    /* Modify CMD_PROP_RX command for application needs */




    RF_cmdPropRx.pQueue = &dataQueue;           /* Set the Data Entity queue for received data */
    RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;  /* Discard ignored packets from Rx queue */
    RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;   /* Discard packets with CRC error from Rx queue */
    RF_cmdPropRx.maxPktLen = MAX_LENGTH;        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
    RF_cmdPropRx.pktConf.bRepeatOk = 1;
    RF_cmdPropRx.pktConf.bRepeatNok = 1;

    rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);

    /* Set the frequency */
    RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);

    /* Enter RX mode and stay forever in RX */
    RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &ReciveThePacket, IRQ_RX_ENTRY_DONE);

    while(1);



}





 // ======== main ========

int main(void)
{

 // Call board init functions
 Board_initGeneral();
// Board_initUART();




 // Construct BIOS objects
    Task_Params taskParams ;
    Task_Params_init(&taskParams);
    taskParams.stackSize = TS;
    taskParams.stack = &task0Stack;
    taskParams.priority = TASK_PRIORITY;
    taskParams.arg0 = (UInt)1000000;



    Task_construct(&task0Struct, (Task_FuncPtr)Taskfunction, &taskParams, NULL); //call the function


    BIOS_start();

    return (0);
}

I'm using SDK ble_sdk_2_02_02_25

The same happens when I try rfPacketRx_CC2650_LAUNCHXL_TI example and put osal_snv_init(); in the callback function

Thank you so much for any help

Best Regards

Bassel

  • Hello Bassel,

    I can't say anything directly regarding the error message you are seeing. However, I can add some insight as to possible reasons things may be breaking.

    osal_snv_init() is a initialization function and should only be called once. It would be best if you performed this action in the Taskfunction().
    The osal_snv_init() function also has a return value that you are not checking. For all we know osal_snv_init() is failing, which would be why the reads and writes are also failing. Make sure you are checking return codes always.

    Please make this correction and let me know what happens!

    Best,
    Kris
  • Hello Kris,
    Thanks so much for replying I have done that but now I'm not able to read or write using osal_snv functions
    The problem as it seems that I'm not able receive and read/write at the same time
    I'm missing something but I couldn't find any way to do both receiving and saving but I can do one of them at a time without any problem
    Best regards
    Bassel
  • Bassel,

    Can you elaborate on how you are testing only writing or reading at a time?

    Are you checking the status that the read and write return? This may give insight as to what the issue is.

    Best,
    Kris
  • Hello kris,
    thanks so much for replying.what I actually meant by writing and reading at a time is that I can put these function in a separate task then I can write and read without problem but of course without receiving any data (write a simple string or so)but when I try to do that using the code above then the program breaks and I can't get the status or do anything and if I try to put the osal_snv_init() in the task and leave the reading and writing functions in the ReciveThePacket function I got nothing at all the program it seems that it stuck somewhere and it never continue or that what I have understood at least .
    it seems that I should put osal_snv_init() and the reading and writing in the same task to work but in this case I can't save the received packet
    Best regards
    Bassel
  • Bassel,

    I think at this point you'll need to see what is actually going on with the debugger. You'll be able to see where the program breaks, possibly why, as well as what return statuses are before the program break.

    At this stage it is best to gain as much understanding as possible. Usually easier said than done. But often you will gain some insight as to what's going on.

    I would suggest taking a look at the Debugging section of the User's Guide for help with debugging.
    dev.ti.com/.../

    Best,
    Kris
  • Hello kris ,

    thank you so much for replying I had discovered the problem there was actually two problems :

    the first one was the time of sending and because I send lots of information I should make it a little bit longer and the second one was this function: RFQueue_nextEntry();

    it makes the program always waits for the next packet without going further or saving anything.

    but now I have another problem:

    I can now send the data to my device and it receives it and save it successfully but I reach a point in which the memory is full and I can't receive anymore because of this 'if condition which prevent anymore data from coming by putting the system in an infinite while loop but I don't want that to happen and I want the system to work forever so I was wondering if there is anyway to free the old memory cells and reuse them after for example ten packet without using one cell to receive them all

    thank you so much for any help

    Best regards

    Bassel

  • Bassel,

    Can you post your new code after the changes you've made. I'm not sure what "if condition" you're referring to. Additionally, please take a look at this SNV page in the documentation. It may be of use to you.

    I'd like to clarify that in your code you are reffering to FlashAddr as the address in NV where the data is being stored. That is not accurate. The snv_write call uses the first parameter as an id for that item. The item id has nothing to do with memory locality. Taking a look at the documentation linked above should help clear this up!

    Lastly, please be aware that if you're using OAD in your project, you should change the NV_ITEM_ID you're using to 0x81. There is a small bug where the OAD module is making use of 0x80 when it shouldn't be. This will be corrected in the next release.

    Best,

    Kris

  • Bassel,

    After reviewing your code more closely from your original post, I would like to add a few suggestions.

    static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */

    Is not being used. you perform a memcpy into it. But then you immediately strcpy the contents into another buffer.

            /* Copy the payload + the status byte to the packet variable */
            memcpy(packet, packetDataPointer, (packetLength + 1));
            strcpy (MemBuffWrite,packet);
    

    You can remove the uint8_t packet buffer and go directly to the MemBuffWrite buffer.

    You are also performing a malloc and free on MemBuffWrite and MemBuffRead on every call to ReciveThePacket()

        MemBuffRead= (uint8*)malloc (30*sizeof(uint8));
        MemBuffWrite = (uint8*)malloc (30*sizeof(uint8));
    
    

    It is best to not use dynamic memory allocation if at all possible. It does not seem necessary to use dynamic memory allocation here since you know a static length of memory you desire. You have hardcoded the value to be 30 bytes here. This can be done at compile time by creating a static buffer similarly to what you did for the uint8_t packet buffer I just spoke of. This will remove complexity, runtime requirements as well as reduce the chance of a memory leak. Rule of thumb: don't malloc unless it's absolutely necessary. In this case, you know the length at compile time. Let the compiler handle it in a safe manner. :) 

    Speaking of memory issues, you seem have one in the for loop of ReciveThePacket() function. You malloc the two buffers. Then enter a for loop. In this for loop you fill the buffers and then read and write to snv. You then free it and perform the next iteration of the For loop. In this case, the first loop is safe but the 2nd - 5th iteration are not. You are now reading and writing to a pointer in which you should no longer have access to since you just free'ed it. This is very dangerous as you've now allowed the memory manager to give this memory region to anything else that asks for it. You could overwrite something else in the heap without knowing it and this is very very bad! 

    Dynamic memory allocation should look like three steps. 

    1. Malloc

    2. use

    3. free

    in your code you have the following

    1. malloc

    2. use

    3. free

    4. repeat steps two and three 5 more times.

    This is very dangerous. Please take a look at this section of the User's Guide to better understand common mistakes with dynamic memory.

    The last thing I'd like to point out is an issue is see is with the usage of strcpy in your for loop. Strcpy() is meant for null terminated c-strings. Not arbitrary data. This is dangerous because many implementations of strcpy will continue copying data until it sees a '\0' (NULL) byte. strcpy, should never be used in general because it is too easy to cause memory overflows. To keep it from overflowing you can use strncpy instead in which you supply the maximum amount of data to be copied. Again though, this is for strings. In your example. If your data were to contain a '\0' , the function would stop there and not copy the rest of the data. Or if it does not include a '\0' byte, it will continue past the end of the packet buffer until it finds a null byte. Copying more data than it should have at address MemBuffWrite. Again, causing memory overflow. 

    If your data is in fact a correctly formatted null terminating string, then strcpy is indeed the correct family of functions to use. In this case though, to protect against a incorrectly formatted null terminating string I suggest you use strncpy in its place. 

  • Hello Kris,

    thank you so much for replying and for correcting all the mistakes in the first code (I have figured out a few of them and they have already been corrected :) but of course not all of them :)  ) it seems that I was mistaken about some stuffs which caused the problem the major thing was the dynamic memory which in fact was the problem so I did what you have suggested and now the program works just fine (I thought of using dynamic memory in order to save the place for other stuffs and I actually figured out that mistake of freeing the buffers and it worked at first but then it stopped so I tried as you suggested to get totally ride of the dynamic memory )

    thank you so much for your help and your wonderful suggestion I really appreciate it :)

    Best regards

    Bassel

  • Bassel,

    You're very welcome! Good luck on the rest of the project :)

    Best,
    Kris