Hi Gaurav,
thanks for quick response…
i think this may be a hardware related issue but… what is weird is the difference between sticking a printf() in the code vs a vTaskDelay… the printf() always works.
Also, the code does not crash it just reads the wrong data from the flash ONLY after certain ERASE cycles…not all ERASE cycles…only every other one, like multiples of N*128… it looks like.
- yes i have those flags set in FreeRTOSConfig.h
- i have stepped thru the code and its somewhat difficult to do im using ModusToolbox and you cannot set conditional breakpoints unfortunately, but when i do step thru the code the read and write pointers look correct
- there are 2 tasks: flash_writer and flash_reader here are some code snips (flash_writer waits for data in a queue, flash_reader waits for the write pointer to pass the read pointer)
- the NAND flash driver i have written using macros like ERASE_BLOCK(), WRITE_FLASH() and READ_FLASH() that actually encapulate low-level QSPI transactions for this particular PSOC6 cpu.
- print_array() is just a function that just does a bunch of printf’s, so it is calling a function there. I noted in the snip below where it passes and fails with “<—”
- flash_reader has the write_page_counter as an extern so it can see it of course
- i dont expect you to dive into the details of the NAND flash and how that works from a QSPI point of view but i am very curious why vTaskDelay() does not work but the print_array() does work
- i have also included a snip of what it looks like when it fails to read the flash correctly and the code checks for “FF” then halts, its as if the flash_reader is reading “too soon” like right after the ERASE but before the next FLASH_WRITE
---------------- flashwriter--------------
void flash_writer(void *params){
write_page_counter = 0;
write_blk_counter = 0;
uint32_t current_space = PAGE_REAL_SIZE;
enum which ping_pong_flag = ping;
ERASE_BLOCK(0);
for(;;){
memset(temp_buff,0,PACKET_SIZE);
xQueueReceive(Q_SensorBuffers, temp_buff, portMAX_DELAY);
// if( xSemaphoreTake( xMutex1, ( TickType_t ) 10 ) == pdTRUE ){
// printf("\r\nflash_writer: wr_pg_ctr: %ld wr_block= %ld space= %ld\r\n",write_page_counter, write_blk_counter, current_space);
// //print_array("flash_writer", temp_buff, 10);
// xSemaphoreGive( xMutex1 );
// }
#if 1
if(temp_buff[2] <= current_space){ /* LEN is third byte in the buffer */
/* (ping_pong_flag==Ping)? (copy into ping):(copy into pong)*/
(ping_pong_flag == ping) ? memcpy(&ping_buff[PAGE_REAL_SIZE-current_space],temp_buff,temp_buff[2]) :
memcpy(&pong_buff[PAGE_REAL_SIZE-current_space],temp_buff,temp_buff[2]);
/* decrement current space by LEN */
current_space -= temp_buff[2];
}
else {
if(ping_pong_flag==ping){
WRITE_FLASH(write_page_counter, ping_buff, (PAGE_REAL_SIZE-current_space));
//printf("\r\nflash_writer: wr_pg_ctr: %ld wr_block= %ld space= %ld\r\n",write_page_counter, write_blk_counter, current_space);
//print_array("writer", ping_buff,16);
/* put the last queue entry into the pong buffer */
memcpy(pong_buff, temp_buff, temp_buff[2]);
ping_pong_flag = pong;
/* clear the ping buffer */
memset(ping_buff, 0, PAGE_REAL_SIZE);
} /* end of write to PING */
else {
WRITE_FLASH(write_page_counter, pong_buff, (PAGE_REAL_SIZE-current_space));
//printf("\r\nflash_writer: wr_pg_ctr: %ld wr_block= %ld space= %ld\r\n",write_page_counter, write_blk_counter, current_space);
//print_array("writer", pong_buff,16);<---WORKS!
vTaskDelay(10); <<---FAILS
/* put last queue entry into the ping buffer */
memcpy(ping_buff, temp_buff, temp_buff[2]);
ping_pong_flag = ping;
/* clear the pong buffer */
memset(pong_buff, 0, PAGE_REAL_SIZE);
} /* end of write to PONG */
/* set current space = 2048 */
current_space = PAGE_REAL_SIZE;
write_page_counter++;
/* check for getting close to block boundary ! */
if (((write_page_counter) % 64) == 0){
printf("\r\ntime to erase next block!\r\n");
write_blk_counter++;
ERASE_BLOCK(write_blk_counter<<6);
}
} /* end of ELSE, which means WRITE FLASH happened */
/* wrap around when full */
if(write_page_counter == 0x20000){
if( xSemaphoreTake( xMutex1, ( TickType_t ) 10 ) == pdTRUE ){
printf("\r\nFLASH FULL- WRAPPING\r\n");
xSemaphoreGive( xMutex1 );
}
write_page_counter = 0;
write_blk_counter = 0;
ERASE_BLOCK(write_blk_counter<<6);
current_space = PAGE_REAL_SIZE;
}
#endif
} /* END OF for(;;) LOOP */
} /* END OF flash_writer */
----------------- flash reader ----------------
extern uint32_t write_page_counter;
static uint32_t read_page_counter = 0;
static uint8_t nand_read_buff[PAGE_SIZE];
void flash_reader(void *params){
/* Read flash for non-0xff data */
for (;;) {
if ((write_page_counter > read_page_counter)){
READ_FLASH(read_page_counter, nand_read_buff, PAGE_REAL_SIZE);
if( xSemaphoreTake( xMutex1, ( TickType_t ) 10 ) == pdTRUE ){
printf("\r\n************FLASH READER: rd_pg_ctr: %ld wr_pg_ctr: %ld **********\r\n",read_page_counter,write_page_counter);
print_array("flash read", nand_read_buff, 16);
xSemaphoreGive( xMutex1 );
if(nand_read_buff[0] == 0xff) vTaskSuspend(NULL);
}
if (read_page_counter == 0x1ffff)
read_page_counter = 0; // account for wrap around
else
read_page_counter++;
} // end of if(...
}
}
---------------flash read WRONG -----------------------------
************FLASH READER: rd_pg_ctr: 126 wr_pg_ctr: 127 **********
flash read (16 bytes):
0xA5 0x8A 0x1E 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02
time to erase next block!
************FLASH READER: rd_pg_ctr: 127 wr_pg_ctr: 128 **********
flash read (16 bytes):
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
------------------- flash read CORRECT --------------------
************FLASH READER: rd_pg_ctr: 126 wr_pg_ctr: 127 **********
flash read (16 bytes):
0xA5 0x8A 0x1E 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02 0x02
writer (16 bytes):
0xA5 0x8D 0x0A 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0xA5 0x8B 0x46 0x03 0x03 0x03
time to erase
********* next block!***FLASH RE
ADER: rd_pg_ctr: 127 wr_pg_ctr: 128 **********
flash read (16 bytes):
0xA5 0x8D 0x0A 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0xA5 0x8B 0x46 0x03 0x03 0x03