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/LAUNCHXL-CC2640R2: uint8 compiler error with an SDK driver example

Part Number: LAUNCHXL-CC2640R2
Other Parts Discussed in Thread: CC2640

Tool/software: TI C/C++ Compiler

Hello,

Would appreciate your input on the following issue. I'm using nvsinternal driver example on CC2640R2 to test saving an array of measurements to the internal flash. I'm using 3.10.0.15 SDK

The driver implementation seems straight forward. I'm trying to save few hundred bytes on the internal flash that I will later need to broadcast. I was using the driver example to test writing to the memory and to make use of the UART as debugging terminal. 

However as soon as I started using for loop for (uint8 i; i<sizeof(signature;){code}, I got the following annoying error. I spent quite a bit of time trying to fix it by following some of the recommendations from other posts but no luck. 

compiler failure, below:

"../nvsinternal.c", line 85: error #20: identifier "uint8" is undefined
"../nvsinternal.c", line 85: error #66: expected a ";"
"../nvsinternal.c", line 85: error #20: identifier "i" is undefined

Any thoughts?

  • Do you use nvsinternal example when you see this issue? If so, where do you put your "for loop for (uint8 i; i<sizeof(signature;){code}"?

  • Correct as indicated in the compiler error below, I use nvsinternal and the for loop is place in nvsinternal.c under mainThread. 

    "../nvsinternal.c", line 85: error #20: identifier "uint8" is undefined
    "../nvsinternal.c", line 85: error #66: expected a ";"
    "../nvsinternal.c", line 85: error #20: identifier "i" is undefined

  • Can you show me the code you add?

  • /*
    * ======== mainThread ========
    */
    void *mainThread(void *arg0)
    {
    NVS_Handle nvsHandle;
    NVS_Attrs regionAttrs;
    NVS_Params nvsParams;

    Display_Handle displayHandle;

    Display_init();
    NVS_init();

    displayHandle = Display_open(Display_Type_UART, NULL);
    if (displayHandle == NULL) {
    /* Display_open() failed */
    while (1);
    }

    NVS_Params_init(&nvsParams);
    nvsHandle = NVS_open(Board_NVSINTERNAL, &nvsParams);
    for (uint8 i; i< sizeof(signature);)
    {
    Display_printf(displayHandle, 0, 0, "for loop counter: ", i);
    i++;
    Display_printf(displayHandle, 0, 0, "\n");
    }

    if (nvsHandle == NULL) {
    Display_printf(displayHandle, 0, 0, "NVS_open() failed.");

    return (NULL);
    }

    Display_printf(displayHandle, 0, 0, "\n");

    /*
    * This will populate a NVS_Attrs structure with properties specific
    * to a NVS_Handle such as region base address, region size,
    * and sector size.
    */
    NVS_getAttrs(nvsHandle, &regionAttrs);

    /* Display the NVS region attributes */
    Display_printf(displayHandle, 0, 0, "Region Base Address: 0x%x",
    regionAttrs.regionBase);

    Display_printf(displayHandle, 0, 0, "Sector Size: 0x%x",
    regionAttrs.sectorSize);
    Display_printf(displayHandle, 0, 0, "Region Size: 0x%x\n",
    regionAttrs.regionSize);


    /*
    * Copy "sizeof(signature)" bytes from the NVS region base address into
    * buffer. An offset of 0 specifies the offset from region base address.
    * Therefore, the bytes are copied from regionAttrs.regionBase.
    */
    NVS_read(nvsHandle, 0, (void *) buffer, sizeof(signature));

    /*
    * Determine if the NVS region contains the signature string.
    * Compare the string with the contents copied into buffer.
    */
    if (strcmp((char *) buffer, (char *) signature) == 0) {

    /* Write signature directly from the NVS region to the UART console. */
    Display_printf(displayHandle, 0, 0, "%s", regionAttrs.regionBase);
    Display_printf(displayHandle, 0, 0, "Erasing flash sector...");

    /* Erase the entire flash sector. */
    NVS_erase(nvsHandle, 0, regionAttrs.sectorSize);
    }
    else {

    /* The signature was not found in the NVS region. */
    Display_printf(displayHandle, 0, 0, "Writing signature to flash...");

    /* Write signature to memory. The flash sector is erased prior
    * to performing the write operation. This is specified by
    * NVS_WRITE_ERASE.
    */
    NVS_write(nvsHandle, 0, (void *) signature, sizeof(signature),
    NVS_WRITE_ERASE | NVS_WRITE_POST_VERIFY);
    }

    Display_printf(displayHandle, 0, 0, "Reset the device.");
    Display_printf(displayHandle, 0, 0, FOOTER);

    return (NULL);
    }

  • You can use the following codes to fix your problem.

        int i;
        for (i=0; i< sizeof(signature);)
        {
        Display_printf(displayHandle, 0, 0, "for loop counter: ", i);
        i++;
        Display_printf(displayHandle, 0, 0, "\n");
        }
    

  • Thanks YK,

    Yes, the for loop works when the variable is defined separately as you correctly suggested. However, I used the original syntax before and it was working. Do you know why uint8 couldn't be triggered in the orig proposed format? 

  • You might need to add related header file in your nvsinternal.c to use uint8.

  • It will be great if you can point me to the right library in case i need to utilize uint8 variable types in the future in other project. 

    Thanks for your help

  • Also, in this case, what will be the best methodology to write 52 bytes consecutively using the for loop? The main purpose is to track the memory address so when a read is performed we're locked in to the proper memory address. 

  • You can add the line "typedef unsigned char   uint8;" before you want to use uint8 variable type. By the way, I think the best methodology to write 52 bytes consecutively is using memcpy.

  • Thanks again YK,

    It will be great if you can provide an example. 

  • What example do you need?

  • To write 52 bytes consecutively to internal flash using memcpy

  • Sorry to misunderstanding your intention. Since you want to write 52 bytes consecutively to internal flash, you should use NVS_write, not memcpy.

    For example, you can use the following sample codes to write 52 bytes data in buf array into internal flash.

    unsigned char buf[52];

    NVS_write(nvsHandle, 0, (void *) buf, 52, NVS_WRITE_ERASE | NVS_WRITE_POST_VERIFY);

  • Thank you for clarifications, the use of memcpy was confusing indeed. 

    So would the below code be correct to write 52 bytes to the flash, one byte at the time? 

    //saving new data
    for (i=0; i< sizeof(signature);) //signature is 52 bytes
    {
    buf[i]=1+i;
    Display_printf(displayHandle, 0, 0, "for loop to write : ", buf[i]);
    //NVS_write(handle return from NVS_open, offset byte, buffer containing data to be written to NVS region, buffer size, flags)
    NVS_write(nvsHandle, 0, (void *)buf[i], sizeof(buf[i]), NVS_WRITE_ERASE|NVS_WRITE_POST_VERIFY);
    i++;

    }

    //recalling stored data
    for (i=0; i< sizeof(signature);) //signature is 52 bytes
    {
    buf[i]=1+i;
    Display_printf(displayHandle, 0, 0, "for loop to reading: ", buf[i]);
    //NVS_read(handle return from NVS_open, offset byte, reading buffer, buffer size)
    NVS_read(nvsHandle, 0, (void *)buf[i], sizeof(buf[i]));
    i++;

    }

  • I already show you the sample code to write 52 bytes. Why do you insist using for -loop?

  • What I'm sharing is test code, my actual code will have to execute more tasks each time during each for iteration. As well, more data will be saved at different portions of the code. I want to make sure there's no confusion to ensure I'm pointing to the correct address.

  • If you do write to internal flash so frequently, it might break the internal flash soon. I would suggest you to use external flash or EEPROM if you need to write data frequently.

  • Yes i understand that's why i'm trying to be careful to lock into the correct address every time there's a read or write incident. It should be feasible without causing issues since the total amount of data is limited (less than 100 bytes). It will be greatly helpful if you can elaborate on the read/write to memory within the For - Loop example I proposed. Thank you.

  • Let me clarify one point first. Will you run BLE application on your LAUNCHXL-CC2640R2?

  • If you will use BLE Stack, you should use osal_snv_write to do internal flash write and the range of ID is between 0x80 and 0x8F only. You can refer to for osal_snv_write example.

  • Thank you for the link. However my application is consuming less than 80kB and I'm not sure why I would have to use OSAL and get limited by 0x80 to 0x8F size? Are you saying there's no other way to utilize the remaining flash blocks?

  • Maybe you can refer to first.

  • Thank you, 

    can you please help on how would you implement a read/write for few bytes using For-Loop?

  • By using osal_snv_write, we will write a buffer with multiple bytes data into flash and won't do byte-by-byte write using a for-loop.

  • In the SNV ID area,  0x80 to 0x8F, how much memory is available? Would each ID contain a full page of available space? Would that mean, we have 16 * 4kB = 64kB of available space?

  • Total is 4K, each SNV ID can be written up to 256 bytes.

  • Thank you, this makes sense. In this case, NVS_write is addressed to SNV 0x0001D000 to 0x0001E000, correct?

  • Yes, osal_snv_write uses address between 0x0001D000 and 0x0001E000.

  • How much memory is available between 0x0001D000 and 0x0001E000? 4kB x8?

  • 0x0001E000-0x0001D000=0x1000 which is 4096(=4K) in decimal.

  • Hi YK,

    Following up on this thread, I have a similar question regarding OSAL_SNV_Read/Write and your help would be greatly appreciated.

    In my case, CC2640 is triggered by an external event to wake up the SOC to measure sensor parameter then store the data to the flash then shuts down again waiting for the external trigger to be repeated or reinitiated. The external trigger is High signal on one of the GPIOs.

    If I use OSAL_SNV_write(0x80, 2, (uint_t *) write_buffer) within the For Loop inside the taskFxn function, how can I keep track of the data being written within each page. Is this done automatically? For instance every time I'm writing to the flash using OSAL_SNV_write(0x80, 2, (uint_t *) write_buffer) it will automatically write data in the available flash page? In that case all I have to keep track of is the number of bytes being written per page?

    You mentioned that each page is 256 bytes. If the 256 bytes are consumed how would I update the 0x80 to 0x81? In other words, is there a way to know when we reach end of the page or I simply have to use the counter? In my case I can clear the flash every 1kB but not sooner and I would like to have a mean to do this robustly.

    Thank you.

  • The content written into each NV ID by osal_snv_write is controlled by your application. I suppose you have to book keeping it by yourself in your application.

  • Thanks for your fast reply,

    Would this mean, book keeping to ensure that we've reached end of the page? In this case is it safe to assume every time we are storing new data in the same page, it will be automatically stored in available new space within the page and that it will not overwrite old data?

  • No, osal_snv_write only write from beginning of each NV ID. You have to manage the write buffer by yourself.

  • The down side in my case is that the system shuts down and I need to log the data on each event. If osal_snv_write starts at the beginning every time, how can I write my new data within the same page, say 0x80, without overriding the old date? Do you have an example? Is there a way to offset the writing pointer?

  • You can read original data out to your buffer, append new data to the buffer, and write the buffer back.

  • Good suggestion, thank you. Let me try and let you know if I have any follow up questions. Appreciate the fast responses.

  • One more question, what's the maximum buffer length I can use with OSAL_SNV_read()? 256?