cancel
Showing results for 
Search instead for 
Did you mean: 

Writing in flash inside a for(;;) loop (in a task) has a non intended behavior

frontinus
Associate

I am Writing in a W25Q128 flash memory with a Cortex M4 microcontroller and FreeRtos operative system.

 

I created a task to write data in my W25Q128 flash.

 

However I noticed that when writing data in the flash thanks to the function Flash_Write (will post it and every lower level function) at a memory address saved in a variable and then incrementing the variable from one for(;;) iteration to another then the data saving in the flash would not occur as it should. In fact while debugging the code and only doing 1 iteration of the for(;;) loop the data is written multiple times with the address incrementing, when it should only write it once, it's also very disturbing that the address increases before the line is executed

Here is an example of the code

 

 

 

 

    gg = 100;
    for(;;){
    	uint32_t *pointer = ≫

    	Flash_Write(gg,(uint8_t*)"bang",4);
    	uint32_t temp = *pointer;
    	*pointer = temp + 4;
    }

 

 

 

and here what only 1 ieteration of flash_write (while debugging) saves

photo_2024-10-06_17-48-19.jpg

 

Worth also mentionning that outside of thoses for(;;) loops everything works correctly, I a priori also cannot fix my problem simply by removing the for(;;) loop because it's inside a FreeRtos task

 

now Flash_Write: 

 

 

 

 

 

void Flash_Write(uint32_t addr, uint8_t* data, uint32_t dataSize){
uint8_t buffer[4];
uint16_t quota;
uint32_t inpage_addr;

	if (dataSize==0)
		return;

	// quota is the data size trasferred until now
	quota=0;

	// define the starting write position inside the first Flash page to write...
	inpage_addr=addr & (EXT_FLASH_PAGE_SIZE-1);

	// ... so I can detect if more than 1 Flash page has still to be written
	while ((dataSize-quota+inpage_addr)>EXT_FLASH_PAGE_SIZE){
	//loop here inside, until more than 1 Flash page...

		Flash_Select();
		buffer[0] = W25_W_ENABLE;
		Flash_Transmit(buffer, 1);
		Flash_UnSelect();
		Flash_SimpleWriteAPage(addr+quota,data+quota,(EXT_FLASH_PAGE_SIZE-inpage_addr));
		quota+=(EXT_FLASH_PAGE_SIZE-inpage_addr);
		// having aligned data to page border on the first writing
		// next writings start from 0 position inside a page
		inpage_addr=0;
		Flash_WaitForWritingComplete();
	}
	// now just the final Flash page...
	if (dataSize-quota) {
		Flash_Select();
		buffer[0] = W25_W_ENABLE;
		Flash_Transmit(buffer, 1);
		Flash_UnSelect();
		Flash_SimpleWriteAPage(addr+quota,data+quota,dataSize-quota);
		Flash_WaitForWritingComplete();
	}
}

 

 

 

 

 

 

 

 

 

 

 

void Flash_SimpleWriteAPage(uint32_t addr, uint8_t* data, uint16_t dataSize){
uint8_t buffer[4];
	buffer[0] = W25_PAGE_P;
	buffer[1] = (addr >> 16) & 0xFF;
	buffer[2] = (addr >>  & 0xFF;
	buffer[3] = addr & 0xFF;
	Flash_Select();
	Flash_Transmit(buffer, 4);
	Flash_Transmit(data, dataSize);
	Flash_UnSelect();
}
void Flash_Transmit(uint8_t* data, uint16_t dataSize){
#ifndef	EXT_FLASH_SPI_POLLING_MODE
	if (dataSize<EXT_FLASH_DMA_CUTOFF) {
#endif //FLASH_SPI_POLLING_MODE
		HAL_SPI_Transmit(&FLASH_SPI_PORT , data, dataSize, HAL_MAX_DELAY);
#ifndef	EXT_FLASH_SPI_POLLING_MODE
	} else {
		HAL_SPI_Transmit_DMA(&EXT_FLASH_SPI_PORT , data, dataSize);
	}
#endif  //FLASH_SPI_POLLING_MODE
}

 

 

 

 

 

 

If you feel that you need more context ask me, thank you in advance for your time

0 REPLIES 0