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.

Understanding task stack and NVS_write()

Hi,

I need some help to understand why a function don't work when called from a task context.

The function below serializes the content of a struct (memoryCopy) to a buffer, then writes it to the flash memory.

void memory_setCopy(void)

{
	uint32_t result;
	uint32_t size;
	uint8_t buffer[4096];
	
	/* Fill the temporary buffer with zeros */
	memset(buffer,0x00,sizeof(buffer));

	/* Serialize the struct */
	memcpy(buffer,&memoryCopy,sizeof(memoryCopy));

	/* Make sure size is a multiple of 4 */
	size = (sizeof(memoryCopy) + 4) & 0xFFFFFFFFC;

	/* Update the memoryCopy in the flash */
	result = NVS_write(nvsHandle,0,buffer,size,NVS_WRITE_ERASE | NVS_WRITE_VALIDATE);
	if(result != NVS_SOK) {
		System_abort("NVS_write failed!\n");
	}
}

I have tested it in the beggining of main(), before calling the tasks and BIOS initialization and it works fine.

Now, when I call it within a task, the program never returns from NVS_write().

I guess it is related with the task stack size, which is now configured to be 1024.

Can someone explain the problem here?

Tanks in advance.

  • Lucas Schuch said:
    Now, when I call it within a task, the program never returns from NVS_write().

    NVS_write() acquires a Semaphore before proceeding into a mutually exclusive region (as does NVS_open() and NVS_read() APIs).  I suspect you're hitting that Semaphore_pend() call and blocking.

    Are you calling NVS_init()?  That function constructs the Semaphore 'writeSem'.

    Is there more than one Task calling NVS APIs?

    Lucas Schuch said:
    I guess it is related with the task stack size, which is now configured to be 1024.

    I don't think task stack size is the problem, at least not for now.

    Lucas Schuch said:
    I have tested it in the beggining of main(), before calling the tasks and BIOS initialization and it works fine.

    It probably appears to work fine since BIOS has not been activated yet, and therefore Semaphore operations aren't really active.

    You can see the NVS implementation by looking in <tidrivers_install>/source/ti/drivers/nvs/*.c (* meaning look in the source file corresponding to your board).

    Regards,

    - Rob

  • > Are you calling NVS_init()?  That function constructs the Semaphore 'writeSem'.

    Yes, here is my init function:

    void memory_init(void)
    {
    	/* The device sector size is critical to the NVS driver,
    	 * check if the configured value is correct! */
    	if(FlashSectorSizeGet() != SECTOR_SIZE) {
    		System_abort("Incorrect sector size!\n");
    	}
    
    	NVS_init();
    
    	/* Get a NVS handle to write and read.
    	 * Note: we are using default parameters. */
    	nvsHandle = NVS_open(CC1310_LAUNCHXL_NVS1F000,NULL);
    }

    > Is there more than one Task calling NVS APIs?

    No, I have only one task in my code.

    New information about the problem:

    In order to test it, I changed the buffer size from 4096 bytes to 512 bytes and now it works.

    Does it explain something?

  • Lucas Schuch said:
    {
        uint32_t result;
        uint32_t size;
        uint8_t buffer[4096];

    In order to test it, I changed the buffer size from 4096 bytes to 512 bytes and now it works.

    Does it explain something?

    I didn't notice that large size, and your suspicion about task stack size is spot on - you are declaring a function local buffer of 4096 bytes, which is allocated from the Task stack.  You will need to either change this buffer to be a non-local or global variable, or you can make your local buffer be 'static', or you can increase your Task stack size to be some amount > 4096 (maybe 4096 + 512), if you want it to be that large.

    Regards,

    - Rob

  • Thank you very much for your reply!