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
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.
Hi
To clarify the situation - uTasker contains no pre-compiled libraries and all code is included as source code.
Regards
Mark
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
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