Implement example flexspi_nor_polling_transfer in project based on FreeRTOS

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Implement example flexspi_nor_polling_transfer in project based on FreeRTOS

1,758 Views
nbe
Contributor II

I try to work with flash memory on MIMXRT1020-EVK

I added files from SDK example, after calling flexspi_nor_flash_init(EXAMPLE_FLEXSPI) my program have an error in line 236, file fsl_flexspi.c.

How to find and fix this problem?

0 Kudos
3 Replies

1,230 Views
simpledeveloper
Contributor II

Solved
Problem is freertos preemption during flash operations.
In the middle of the execution of some evkmimxrt1060_flexspi_nor_polling_transfer operations in flash (in particular into FLEXSPI_TransferBlocking), freertos tries to fetch instructions from flash, busy flash gives wrong values to the instruction unit, 0xFFFFFFFD in my case corresponding to a Reserved portion of the memory map table, resulting into hard fault.

Solution: taskENTER_CRITICAL() and taskEXIT_CRITICAL() before and after every single flash operation into evkmimxrt1060_flexspi_nor_polling_transfer , blocking all interrupts during every single flash operation of the example.

 

        taskENTER_CRITICAL();
	flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
	taskEXIT_CRITICAL();

	PRINTF("\r\nFLEXSPI example started!\r\n");

	/* Get vendor ID. */
	taskENTER_CRITICAL();
	status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
	taskEXIT_CRITICAL();
	if (status != kStatus_Success)
	{
		return status;
	}
	PRINTF("Vendor ID: 0x%x\r\n", vendorID);

#if !(defined(XIP_EXTERNAL_FLASH))
	/* Erase whole chip . */
	PRINTF("Erasing whole chip over FlexSPI...\r\n");

	status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
	if (status != kStatus_Success)
	{
		return status;
	}
	PRINTF("Erase finished !\r\n");

#endif

	/* Enter quad mode. */
	taskENTER_CRITICAL();
	status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
	taskEXIT_CRITICAL();
	if (status != kStatus_Success)
	{
		return status;
	}

	/* Erase sectors. */
	PRINTF("Erasing Serial NOR over FlexSPI...\r\n");
	taskENTER_CRITICAL();
	status = flexspi_nor_flash_erase_sector(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE);
	taskEXIT_CRITICAL();
	if (status != kStatus_Success)
	{
		PRINTF("Erase sector failure !\r\n");
		return -1;
	}

	memset(s_nor_program_buffer, 0xFFU, sizeof(s_nor_program_buffer));

	DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);

	memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
		   sizeof(s_nor_read_buffer));

	if (memcmp(s_nor_program_buffer, s_nor_read_buffer, sizeof(s_nor_program_buffer)))
	{
		PRINTF("Erase data -  read out data value incorrect !\r\n ");
		return -1;
	}
	else
	{
		PRINTF("Erase data - successfully. \r\n");
	}

	for (i = 0; i < 0xFFU; i++)
	{
		s_nor_program_buffer[i] = i;
	}

	taskENTER_CRITICAL();
	status =
		flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE, (void *)s_nor_program_buffer);
	taskEXIT_CRITICAL();
	if (status != kStatus_Success)
	{
		PRINTF("Page program failure !\r\n");
		return -1;
	}

	DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);

	memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
		   sizeof(s_nor_read_buffer));

	if (memcmp(s_nor_read_buffer, s_nor_program_buffer, sizeof(s_nor_program_buffer)) != 0)
	{
		PRINTF("Program data -  read out data value incorrect !\r\n ");
		return -1;
	}
	else
	{
		PRINTF("Program data - successfully. \r\n");
	}

 

 Please consider to give kudos ans mark this answer as "solution" for the community.

0 Kudos

1,244 Views
simpledeveloper
Contributor II

Hi everyone,
did someone make progress on this topic?
I'm encountering the same problem.
At first I developed a FreeRTOS code doing other stuff, imported nxp example evkmimxrt1060_flexspi_nor_polling_transfer relevant files and configurations, but code crashed almost instantaneously.
Then to verify that every small difference from nxp example to mine own project are ok, I simply added into the nxp example the freertos task doing the exact same things the previous baremetal main did, and suddenly the flash started hardfaulting and also reebooting!

int main(void)
{
    BOARD_ConfigMPU();
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

if (xTaskCreate(flwexspi_nor_polling_task, "flwexspi_nor_polling_task", 512, NULL, 3, NULL) != pdPASS)
	{
		PRINTF("Task creation failed.");
	}

    vTaskStartScheduler();
    
    //code section never reached
    return 0;
}

and then the task simply is

void flwexspi_nor_polling_task(void *param)
{
	uint32_t i = 0;
	status_t status;
	uint8_t vendorID = 0;

	 flexspi_nor_flash_init(EXAMPLE_FLEXSPI);

	    PRINTF("\r\nFLEXSPI example started!\r\n");

	    /* Get vendor ID. */
	    status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
	    if (status != kStatus_Success)
	    {
	        return status;
	    }
	    PRINTF("Vendor ID: 0x%x\r\n", vendorID);

	#if !(defined(XIP_EXTERNAL_FLASH))
	    /* Erase whole chip . */
	    PRINTF("Erasing whole chip over FlexSPI...\r\n");

	    status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
	    if (status != kStatus_Success)
	    {
	        return status;
	    }
	    PRINTF("Erase finished !\r\n");

	#endif

	    /* Enter quad mode. */
	    status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
	    if (status != kStatus_Success)
	    {
	        return status;
	    }

	    /* Erase sectors. */
	    PRINTF("Erasing Serial NOR over FlexSPI...\r\n");
	    status = flexspi_nor_flash_erase_sector(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE);
	    if (status != kStatus_Success)
	    {
	        PRINTF("Erase sector failure !\r\n");
	        return -1;
	    }

	    memset(s_nor_program_buffer, 0xFFU, sizeof(s_nor_program_buffer));

	    DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);

	    memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
	           sizeof(s_nor_read_buffer));

	    if (memcmp(s_nor_program_buffer, s_nor_read_buffer, sizeof(s_nor_program_buffer)))
	    {
	        PRINTF("Erase data -  read out data value incorrect !\r\n ");
	        return -1;
	    }
	    else
	    {
	        PRINTF("Erase data - successfully. \r\n");
	    }

	    for (i = 0; i < 0xFFU; i++)
	    {
	        s_nor_program_buffer[i] = i;
	    }

	    status =
	        flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE, (void *)s_nor_program_buffer);
	    if (status != kStatus_Success)
	    {
	        PRINTF("Page program failure !\r\n");
	        return -1;
	    }

	    DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);

	    memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
	           sizeof(s_nor_read_buffer));

	    if (memcmp(s_nor_read_buffer, s_nor_program_buffer, sizeof(s_nor_program_buffer)) != 0)
	    {
	        PRINTF("Program data -  read out data value incorrect !\r\n ");
	        return -1;
	    }
	    else
	    {
	        PRINTF("Program data - successfully. \r\n");
	    }

	    while (1)
	    {
	    }
}

Ads I said, nothing changed except for the FreeRTOS initialization and usage!

Any suggestion?

0 Kudos

1,593 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Nazarii,

  Do you run the official flexspi_nor polling project directly on your side, whether it works or not?

  Besides, if your modified project have problems, it's better to share the whole project which can reproduce the problem, then we can help you to check it more easily.


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos