FlexRAM configuration for OCRAM = 0

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

FlexRAM configuration for OCRAM = 0

2,285 Views
nickwallis
Senior Contributor I

I am using RT1062, and I would like to change flexRAM configuration for ITCM=256KB DTCM=256KB and OCRAM=0 (with RT1062 we already have 512KB of fixed OCRAM that is separate to flexRAM).

To do this, one of the things you have to change is the memory configuration in function BOARD_ConfigMPU() in file board.c

However, there is no #define for a memory size of zero (0) for the OCRAM setting that I need in file mpu_armv7.h

My question - how do I set the OCRAM size to zero (0) in BOARD_ConfigMPU()?

thanks

-Nick

pastedImage_1.png

pastedImage_3.png

Labels (1)
0 Kudos
7 Replies

2,104 Views
nickwallis
Senior Contributor I

OK thanks Mark.

So it sounds like there is no reason why you can't just set IOMUXC_GPR_GPR14 to ITCM=512KB and DTCM=512KB and be done with it?

-Nick

0 Kudos

2,104 Views
mjbcswitzerland
Specialist V

Nick

Yes, that is my take on it.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos

2,104 Views
mjbcswitzerland
Specialist V

Hi Nick

Since you won't be using the FlexRAM OCRAM region you can remove the region configuration (comment out the two lines), which means that it is disabled (default state) and is equivalent to being set to a size of 0.

However, if you don't access the region either you can just leave the standard configuration for the MPU too since it will never be used anyway.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos

2,104 Views
nickwallis
Senior Contributor I

OK thanks Mark, I'll give that a try.

A vaguely related point, in another thread (Where is the OCRAM (FlexRAM) in the i.MX Rt 1060? ) you mentioned that you reconfigured the FlexRam to be 480KB DTCM and 32KB ITCM. After reading the reference manual I thought this mix was not possible, because IOMUXC_GPR_GPR14 only has 9 choices for the DTCM total size and 480KB is not one of them. So how does this work please? If you allocate the banks you need correctly in IOMUXC_GPR_GPR17, does the size value in IOMUXC_GPR_GPR14 not matter?

-Nick

pastedImage_932.png

0 Kudos

2,104 Views
mjbcswitzerland
Specialist V

Nick

The bank allocation itself is controlled in IOMUXC_GPR_GPR17 and I set IOMUXC_GPR_GPR14 to a fixed 512k on the 1062 so that the full possible area is covered. Non-modulo sizes are valid since, for example, 448k DTC is a size that can be configured by eFUSE setting. According to the FlexRAM documentation, if you set a modulo value in IOMUXC_GPR_GPR14 that is "smaller" than the DTC any accesses above the size set with hard fault, so allocating 480k DTC and 256k in IOMUX_GPR_GPR14 would mean that only the first 256k of it could physically be accessed without a hard fault but setting it to the next largest (512k) allow all 480k to be accessed - therefore the decision to simply set to the largest possible modulo size.

I use a routine which configures the ITC/DTC according to the size of ITC requested  (since I usually run all code in ITC) - that is, it allocates enough for the code that is to be run and any left over to DTC.

// This code runs in QSPI flash and configures the flexRAM for subsequent operation
// - only stack variables are used which remain valid after the FlexRAM configuration
//
static unsigned char *fnConfigureFlexRAM(unsigned long ulCodeSize)
{
    unsigned char *ptrTopOfRAM;
    int i = 0;
    unsigned long ulBankConfig = 0;
    register unsigned long ulFlexRamConfig = (IOMUXC_GPR_GPR16_FLEXRAM_BANK_CFG_SEL_CFG | IOMUXC_GPR_GPR16_RESERVED); // select the configuration (rather than from fuse values)
    volatile unsigned long ulRemapAddress = (unsigned long)IOMUXC_GPR_GPR16_ADD;
    volatile register signed long slOffset;
    int iOCRAM_banks = 0;
    int iDTC_banks;
    int iITC_banks;
    #if !defined ENABLE_DATA_CACHE
    int iOCRAM_banks_needed;
    #endif
    iITC_banks = ((ulCodeSize + (FLEX_RAM_GRANULARITY  - 1))/FLEX_RAM_GRANULARITY); // the number of RAM banks required for code
    iDTC_banks = (FLEX_RAM_BANKS - iITC_banks);                          // reset for data
    ptrTopOfRAM = (unsigned char *)(RAM_START_ADDRESS_DTC + (iDTC_banks * FLEX_RAM_GRANULARITY));

    // Strategy is to put code into ITCM and allocate remaining banks for DTCM - without using OCRAM
    // - larger programs will need to change the strategy to run partly in QSPI Flash or use other external memory
    // 

    // Configure FlexRAM
    //
    #if SIZE_OF_FLEX_RAM >= (512*1024)                                   // set the highest power of two size for the flexram that is available
    IOMUXC_GPR_GPR14 = (IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_512K | IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_512K); // define the memory type sizes
    #elif SIZE_OF_FLEX_RAM >= (256*1024)
    IOMUXC_GPR_GPR14 = (IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_256K | IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_256K); // define the memory type sizes
    #else
    IOMUXC_GPR_GPR14 = (IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_128K | IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_128K); // define the memory type sizes
    #endif
    if ((iOCRAM_banks + iITC_banks + iDTC_banks) > FLEX_RAM_BANKS) {
        _EXCEPTION("Too many RAM banks defined!");
    }
    #if defined iMX_RT1011
    slOffset = -((1 - iDTC_banks) * FLEX_RAM_GRANULARITY);
    #else
    slOffset = -((FLEX_RAM_BANKS/2 - iDTC_banks) * FLEX_RAM_GRANULARITY);
    #endif
    #if !defined ENABLE_DATA_CACHE
    iOCRAM_banks_needed = iOCRAM_banks;
    #endif
    // The banks are ordered starting with instruction use, followed by (if used) OCRAM use, and always ending with data use
    //
    if (iDTC_banks != 0) {
        ulFlexRamConfig |= IOMUXC_GPR_GPR16_INIT_DTCM_EN;
    }
    if (iITC_banks != 0) {
        ulFlexRamConfig |= IOMUXC_GPR_GPR16_INIT_ITCM_EN;
    }
    while (iITC_banks-- != 0) {
        ulBankConfig |= (IOMUXC_GPR_GPR17_FLEXRAM_BANK_CFG_BANK0_ITCM << i);
        i += 2;
    }
    while (iOCRAM_banks-- != 0) {
        ulBankConfig |= (IOMUXC_GPR_GPR17_FLEXRAM_BANK_CFG_BANK0_OCRAM << i);
        i += 2;
    }
    while (iDTC_banks-- != 0) {
        ulBankConfig |= (IOMUXC_GPR_GPR17_FLEXRAM_BANK_CFG_BANK0_DTCM << i);
        i += 2;
    }
    POWER_UP_ATOMIC(3, FLEXRAM1_CLOCK);                                  // ensure FlexRAM is clocked
    IOMUXC_GPR_GPR17 = ulBankConfig;                                     // define the bank usage
    _SYNCHRONISATION_DATA_BARRIER();                                     // ensure that the bank configuration write has terminated before continuing

    // The stack pointer is adjusted so that it will have the same content after the FlexRAM remap
    //
    slOffset -= ((RAM_START_ADDRESS - RAM_START_ADDRESS_DTC));           // stack moves from top of original OCRAM/ITC to top of DTC 
    fnAdjustStackPointer((volatile unsigned long *)ulRemapAddress, ulFlexRamConfig, slOffset); // adjust the stack pointer and remap FlexRAM (stack pointer is adjusted so that it is in the same FlexRAM bank and thus has the same content before and after the remap)

    #if !defined ENABLE_DATA_CACHE                                       // only possible when data cache is not used
    if (iOCRAM_banks_needed == 0) {
        POWER_DOWN_ATOMIC(3, OCRAM_CLOCK);                               // no OCRAM used so power down
    }
    #endif

    // Now the new FlexRAM configuration is valid and the stack content restored so we can continue
    //
    return ptrTopOfRAM;
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

fnAdjustStackPointer() is a routine (partly assembler) that does the actual swap at run time and preserves the stack so that the change can be performed at any time during an operating program. Since the split is defined at run time rather than being fixed (eg. by eFUSEs or hard defines) it is very suitable for boot loader use to adapt to the actual application that is to operate. It runs compatibly on i.MX RT 1011...1064.

Attached is an "extract" from the uTasker i.MX RT 1060 user's manual explaining the FlexRAM layout strategy.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos

2,104 Views
nickwallis
Senior Contributor I

Thanks for the thorough answer mjbcswitzerland

Regarding "so allocating 480k DTC and 256k in IOMUX_GPR_GPR14":

- There is no option for 480KB anything in IOMUX_GPR_GPR14 (see above)

- 480KB + 256KB, obviously, adds up to more than the available 512KB FlexRAM

I guess what you are saying is, this doesn't matter so long as everything else is setup correctly.

-Nick

0 Kudos

2,104 Views
mjbcswitzerland
Specialist V

Nick

480k DTC and 32k ITC would be a possible FlexRAM configuration.

What I meant was - if you set 480k DTC but set IOMUXC_GPR_GPR14 to 256k you will have allocated 15 of the 16 banks to DTC but you would only be able to physically access 256k (the last 224k would be there but any attempt to access it would hard fault). However of you set IOMUXC_GPR_GPR14 to 512k you will be able to access all of the banks.

Therefore the IOMXC_GPR_GPR14 should best be set up to equal the size (if modulo 2) or be set to the next largest size (eg. 512k in the 480k case) so that it still "envelopes" the memory size.

Generally 512k will fit all....

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

0 Kudos