This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Memory initialization on RM57

Other Parts Discussed in Thread: HALCOGEN

I have been experimenting with different ways to create "No_Init" RAM space, which would be RAM data persistent over reset cycles (but undefined at a power cycle).


My question is, can I use CPU memory writes to initialize RAM?

I've noted that writing 32 bit values to un-initialized RAM causes an ECC error, but writing 64 bit values

asm:  strd  r1, r2, [r4]

on 8 byte boundaries seems to work fine. This makes sense with the 64/8 ECC scheme in hardware, but is this an acceptable and reliable way to initialize RAM on the RM57?

My plan is this:

At start, read no-init RAM space.

If ECC error

      HW init all RAM, clear error, and continue.

If no ECC error

      CPU init RAM *except* no-init RAM space, and continue.

Thanks,

Dan

  • Hello Dan,

      There are two ways to initialize the memory. One way is to use the hardware. Another is the software. If you are using HalCoGen then it is already initializing the CPU SRAM via the  _memInit_(). This function is called in the HL_sys_startup.c file. You can create a similar function as below to initialize other on-chip RAM such as NHET RAM, MibSPI RAM and etc.

    /** @fn void memoryInit(uint32 ram)
    *   @brief Memory Initialization Driver
    *
    *   This function is called to perform Memory initialization of selected RAM's.
    */
    void memoryInit(uint32 ram)
    {
    /* USER CODE BEGIN (6) */
    /* USER CODE END */
    
        /* Enable Memory Hardware Initialization */
        systemREG1->MINITGCR = 0xAU;    
        
        /* Enable Memory Hardware Initialization for selected RAM's */
        systemREG1->MSINENA  = ram;
        
        /* Wait until Memory Hardware Initialization complete */
    	/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
        while((systemREG1->MSTCGSTAT & 0x00000100U) != 0x00000100U)
        { 
        }/* Wait */         
        
        /* Disable Memory Hardware Initialization */
        systemREG1->MINITGCR = 0x5U;    
        
    /* USER CODE BEGIN (7) */
    /* USER CODE END */
    }

    What you pass in the argument to this function is the RAM select number based on  the below mapping. For example, if you want to initialize MibSPI5 RAM you would pass 0x1000 as the argument. You can find the below table in the RM57 datasheet. You can find more information about the MSINENA in the TRM under the System Control Register section.

     You can also use the software to initialize the RAM but it will be very slow as the CPU needs to write to every location. Another problem is that if you write in 32-bit to the CPU RAM, then it forces a read-modify-write operation in order to calculate the ECC based on the 32-bit data coming from the CPU and the other 32-bit data currently in the RAM. After power up, the RAM content is unknown. When you write a 32-bit value to the RAM, it forces a read operation which reads out a unknown data and an unknown ECC checksum. This pair of unknown data and ECC causes an ECC error. When you do a 64-bit write, it does not do read-modify-write. What you write out is what is written to the SRAM along with the ECC checksum generated by the CPU.

      So I will adice you to use the hardware initialization.

  • Charles,

    Thanks for the reply, but that really doesn't answer my questions.

    I've seen the table you listed, and I've read the ... manual.  One interesting thing that I just now realized is that there is a typo in the table, as the MEMINT_ENA register is spelled wrong and not listed anywhere else. I think that should be MEMINIT_ENA instead of MEMINT_ENA.

    Again:

    1) "can I use CPU memory writes to initialize RAM?"

    2) Regarding software RAM initialization in my original post, given the ECC scheme, "is this an acceptable and reliable way to initialize RAM on the RM57?"

    To rephrase my questions another way:

    3) Is there any reason, other than speed, that I cannot reliably initialize ECC RAM on the RM57 by writing using the STRD assembly language instruction (or any single instruction, 2 register aligned write to RAM)?

    I recognize that this takes more time, but processors have been initializing memory this way for 50 years. I don't know why it would be too slow now, especially considering that RW memory is initialized this way, and memory testing is done the same way.


    Thanks,

    Dan

  • Hello Dan,

    What is the No_Init region? Is this the entire RAM or a small region in the RAM? Are you trying to initialize the RAM to zeros or to some other values? The hardware initialization will intialize the entire RAM with zeros.

      If you don't mind the speed of initializing the RAM using CPU compared to the hardware initialization then you can use the CPU to do it. Please note that you should use STRD rather than other write sizes that is less than 64-bit as I explained earlier how the ECC error (due to read-modify-write if any less than 64-bit writes is performed to the RAM right after power up) can be introduced. Since you are suggesting to use STRD then you will be fine. May I ask two questions?

      1. Where would you perform the initialization in your code? Reason for asking is that the CPU can try to save data onto the stack before you initialize the RAM. So make sure your initialization is done early.

      2. What is preventing you to use the hardware initialization?

  • Thanks Charles. That clears it up.

    The No_Init region is an area or RAM that is not cleared to zero at startup, nor is it set to any constant values. A No_Init (or NOINIT) keyword tells the linker to leave alone (do not zero) any variables placed there.  It's used as an area to place variables which must persist through reset cycles, or as a scratchpad to send data from one application image to another.

    Initialization of RAM takes place in the first few instructions, same as any other application; It's just that some variables, ones that persist through resets (a reset counter, for instance), must not be wiped out by the hardware memory reset.

    Nothing prevents me from using hardware to initialize all memory *except* the no_init region. Some of that area is kept for persistent variables, and the rest is cleared by the CPU using the strd instruction.


    Regards,

    Dan

  • Hi Dan,

      One thing I need to caution you is that we don't explicitly state/guarantee the content of the RAM can be preseerved after a reset cycle. You should treat the RAM content as suspect for corruption after a reset cycle and take steps to validate the contents. You can not assume the device will ensure the contents are preserved even if it seems to act like it on the bench. A warm reset can be due to various reset events such as OSC fail, watchdog reset, software reset and external reset. Software reset can be controlled by the CPU but others are not. When a reset happens in the middle of a write operation to the RAM, it can result in corruption of the RAM contents as the timing protocol to the RAM may not be met.