iMX RT1021 - FreeRTOS + LwIP + Relocate FlexRAM

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

iMX RT1021 - FreeRTOS + LwIP + Relocate FlexRAM

338 Views
salva214
Contributor II

Hello everyone,

I’m trying to get a project working for an EVK-RT1020 that uses FreeRTOS + LwIP.

I’ve tried the individual examples (ping, echo, and httpsrv) available in the SDK, but I need to create a new project that makes use of the internal RAM, preferably with all three functionalities.

First, I integrated all the necessary components from SDK, settings and files, taking them from the demo projects, then I reorganized the RAM by allocating 192KB to the DTC, 0KB to the ITC, and 64KB to the OC (following this link: https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Reallocating-the-FlexRAM/ta-p/1117649)

 

// startup_mimxrt1021.c
[...]
__attribute__ ((naked, section(".after_vectors.reset")))
void ResetISR(void) {
    // Disable interrupts
    __asm volatile ("cpsid i");
    //__asm volatile ("MSR MSP, %0" : : "r" (&_vStackTop) : );
[...]
  	/* Reallocating the FlexRAM */
	/*  https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/Reallocating-the-FlexRAM/ta-p/1117649
	 *  DTC=192KB, ITC=0KB, OC=64KB
	 *	{O,O,D,D,D,D,D,D}
	 *	LSB --------> MSB
	 *
	 *	{10,10,10,10,10,10,01,01}
	 *	MSB ---------------> LSB
	 */
	__asm (".syntax unified\n"

	"LDR R0, =0x20001fff\n"//load initial value of stack pointer into R0
	"MSR MSP,R0\n" //re-initialize stack pointer by new value

	"LDR R0, =0x400ac044\n"//Address of register IOMUXC_GPR_GPR17
	"LDR R1, =0xaaa5\n"//FlexRAM configuration DTC = 192KB, ITC = 0KB, OC = 64KB
	"STR R1,[R0]\n"

	"LDR R0,=0x400ac040\n"//Address of register IOMUXC_GPR_GPR16
	"LDR R1,[R0]\n"
	"ORR R1,R1,#4\n"//The 4 corresponds to setting the FLEXRAM_BANK_CFG_SEL bit in register IOMUXC_GPR_GPR16
	"STR R1,[R0]\n"

	".syntax divided\n");

#if defined (__USE_CMSIS)
[...]
// fsl_flexspi_nor_boot.c

#include "fsl_flexspi_nor_boot.h"
/* Relocating Flex-RAM */
extern void ResetISR(void);

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.xip_device"
#endif

#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".boot_hdr.ivt"), used))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.ivt"
#endif
/*************************************
 *  IVT Data
 *************************************/
const ivt image_vector_table = {
    IVT_HEADER,                    /* IVT Header */
    //IMAGE_ENTRY_ADDRESS,           /* Image Entry Function */
	(uint32_t)ResetISR,			   /* Image Entry Function */
    IVT_RSVD,                      /* Reserved = 0 */
    (uint32_t)DCD_ADDRESS,         /* Address where DCD information is stored */
    (uint32_t)BOOT_DATA_ADDRESS,   /* Address where BOOT Data Structure is stored */
    (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
    (uint32_t)CSF_ADDRESS,         /* Address where CSF file is stored */
    IVT_RSVD                       /* Reserved = 0 */
};
[...]
// board.c
[...]
    /* **********************
     * Relocating Flex-RAM
     * **********************
     */
    /* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
    /* ITC Memory */
    MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, 0);

    /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
    /* DTC Memory */
    MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
    /* OC Memory */
    MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64KB);
    /************************/
[...]
// project memory settings
/*
* Type    Name            Alias   Location     Size       Driver
* ----------------------------------------------------------------------------
* Flash   BOARD_FLASH     Flash   0x60000000   0x800000   MIMXRT1020_SFDP_QSPI
* RAM     SRAM_DTC        RAM     0x20000000   0x30000	
* RAM     SRAM_ITC        RAM2    0x0          0x4	
* RAM     SRAM_OC         RAM3    0x20200000   0x10000	
* RAM     BOARD_SDRAM     RAM4    0x80000000   0x1e00000	
* RAM     NCACHE_REGION   RAM5    0x81e00000   0x200000
*/

 

I can compile and run the project, but I can’t ping, neither from the board to the PC nor from the PC to the board: I receive the following log: “lwip_sendto: invalid addressping: send 192.168.1.99” which are two logs concatenated (I don’t understand why without a “/n” between them) ipv6 ping + ipv4 ping.
Why it seems all correctly configured but the ping doesn't work? 

 

// Build console output
Building target: RT1021_LwIP-FreeRTOS_Project.axf
Invoking: MCU Linker
arm-none-eabi-gcc -nostdlib -Xlinker -Map="RT1021_LwIP-FreeRTOS_Project.map" -Xlinker --gc-sections -Xlinker -print-memory-usage -Xlinker --sort-section=alignment -Xlinker --cref -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -T RT1021_LwIP-FreeRTOS_Project_Debug.ld -o "RT1021_LwIP-FreeRTOS_Project.axf" 
[...]
Memory region         Used Size  Region Size  %age Used
     BOARD_FLASH:      184636 B         8 MB      2.20%
        SRAM_DTC:      159640 B       192 KB     81.20%
        SRAM_ITC:          0 GB          4 B      0.00%
         SRAM_OC:          0 GB        64 KB      0.00%
     BOARD_SDRAM:          0 GB        30 MB      0.00%
   NCACHE_REGION:          0 GB         2 MB      0.00%
Finished building target: RT1021_LwIP-FreeRTOS_Project.axf
 
Performing post-build steps
arm-none-eabi-size "RT1021_LwIP-FreeRTOS_Project.axf"; # arm-none-eabi-objcopy -v -O binary "RT1021_LwIP-FreeRTOS_Project.axf" "RT1021_LwIP-FreeRTOS_Project.bin" ; # checksum -p MIMXRT1021xxxxx -d "RT1021_LwIP-FreeRTOS_Project.bin";
   text	   data	    bss	    dec	    hex	filename
 184604	     32	 159564	 344200	  54088	RT1021_LwIP-FreeRTOS_Project.axf

16:25:01 Build Finished. 0 errors, 6 warnings. (took 33s.22ms)
// Serial terminal output
Hello World
Initializing PHY...

************************************************
 PING example
************************************************
 IPv4 Address     : 192.168.1.102
 IPv4 Subnet mask : 255.255.255.0
 IPv4 Gateway     : 192.168.1.99
************************************************
lwip_sendto: invalid addressping: send 192.168.1.99
                                                   lwip_sendto: invalid addressping: send 192.168.1.99
     lwip_sendto: invalid addressping: send 192.168.1.99
                                                        lwip_sendto: invalid addressping: send 192.168.1.99
[...and so on...]

 

From Wireshark, I don’t see packets passing on the PC’s ETH.

I also tried to reduce the stack_init function (stack_init2 is the full one) so it only creates the ping task, avoiding the initialization of the other function tasks (mdns, httpsrv, echo, etc.), but I didn’t succeed.

Did I possibly misconfigure the RAM?

First of all, I don’t understand how to calculate the Stack Pointer address to be loaded in R0 in the assembly code of the startup_mimxrt1021.c file, I used 0x20001fff but this seems correct only when the memory portion for the Stack is 0x2000.

 

// Heap and Stack placement: MCUXpresso Style
       | Region   | Location  | Size
-------|----------|-----------|--------
Heap   | Default  | Post Data | 0x8000
Stack  | Default  | Start     | 0x10000

 

In my case, I had to set at least a Stack of 0x10000 otherwise I received the error message “Task creation failed”.

How do you calculate the necessary Heap and Stack portions quite accurately?

Why is not possible to set ITC Memory to 0? (I had to specify at least 4)

Thank you

0 Kudos
4 Replies

224 Views
salva214
Contributor II

thanks all for the replies

@mjbcswitzerland unfortunately on the project I'm working currently, because of security reasons, I'm not authorized to use uTasker because of some precompiled libraries of which we don't have the source code.

@Omar_Anguiano reading the iMXRT1021 Ref Manual i see that ITCM = 0 is a possible fuses configuration into the Default FlexRAM RAM
bank partioning [ (D=DTCM, I=ITCM, O=ORAM) => 0101: 192KB, 0 KB, 64 KB => {O,O,D,D,D,D,D,D} ], the problem is that the Memory configuration that cannot accept a 0 sized ITCM, so i set ITCM size = 0x4 as workaround (maybe is better to completely remove the line from the memory configuration table?) and that the MPU need a power of 2 as size for the various partitions, so i had to specify 256k for the DTCM instead of 192k. 

Anyway in that project i was maybe trying to put too much functionalities for the RAM i have. Right now i started again a new project, but instead of starting from scratch i started from the ping example, adding the UDP part I manly needed, and it works with about 90k of RAM in use.
The HEAP and STACK used are smaller also (0x7000 for the Heap [Post Data] and 0x800 for the Stack [placed at 'end' instead of 'start' that was mentioned in the KB tutorial])

Even if it is working, i admit that i didn't fully understood the heap and stack sizing and how the ram is occupied by the code during execution. 

0 Kudos

222 Views
mjbcswitzerland
Specialist V

Hi

To clarify the situation - uTasker contains no pre-compiled libraries and all code is included as source code.

Regards

Mark

 

0 Kudos

245 Views
mjbcswitzerland
Specialist V

Hi

See https://youtu.be/fnfLQ-nbscI and consider using the uTasker loader [https://www.utasker.com/iMX/developers.html] which gives OTA / serial loading, encryption and automatic FlexRAM configuration to projects.

Note that code usually resides in ITC and data in DTC since that is what they are designed for, in order to achieve optimal efficiency.

Regards

Mark

 

0 Kudos

260 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

It is possible for ITCM to be 0 on the fuses configuration. If the requested ITCM/DTCM size is 0 Bytes, disable the corresponding TCM in IOMUXC_GPR_GPR16->INIT_xTCM_EN before configuring the size to 0 Bytes in IOMUXC_GPR_GPR14->CM7_CFGxTCMSZ.
It is strongly recommended that the code that reconfigures the FlexRAM is executed from a different type of memory than the ITCM/DTCM/FlexRAM-dedicated OCRAM.

The stack size should be set according to the specific application, unfortunately, there is no standardized guide to calculate the stack for specific applications.

Best regards,
Omar

0 Kudos