cancel
Showing results for 
Search instead for 
Did you mean: 

I want to move the ucHeap of the FreeRTOS from RAM_D1 to External RAM (HYPERRAM)

vishnu_illikkal
Associate III
Board Using - STM32H735G-DK

1. I tried moving the whole .bss section into HYPERRAM

  /* Uninitialized data section into "RAM_D1" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >HYPERRAM  /* RAM_D1 */

 

This causes HardFault Error and the Display is a white screen.
Observation/Guess : maybe because the code that starts the board/MCU is in the bss section and the HYPERRAM is not initialized at the start so the code to initialize the HYPERRAM is inside HYPERRAM. So it is not working.

2. Moving only ucHeap to HYPERRAM

Edited the linkerscript to create a new section

.freertos_data (NOLOAD) :
  {
    . = ALIGN(4);
    _freertos_data_begin = .;
    *(.freertos_data)
    *(.freertos_data*)
    . = ALIGN(4);
    _freertos_data_end = .;
  } >HYPERRAM

Inside FreeRTOS.h file changed the to 1 

#ifndef configAPPLICATION_ALLOCATED_HEAP
	#define configAPPLICATION_ALLOCATED_HEAP 1
#endif

in main.c
created an array for ucHeap

/* USER CODE BEGIN PV */
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".freertos_data")));
/* USER CODE END PV */

 Now downloaded the program using Debug
Error: Program gets HardFault Error even before going into main() function.

I think because i put a breakpoint in first line of main() function it is not reaching and i cannot 'reset` the debug using the reverse curved arrow.
What error is shown: 

vishnu_illikkal_0-1719985981744.pngvishnu_illikkal_1-1719986482100.png

vishnu_illikkal_2-1719987844486.pngheap_4.c having the problem

Observation/Guess : FreeRTOS functions are calling before the init of the External RAM or even before the program is fully start.
Some RWX permission warning also hapening i don't know what that is

vishnu_illikkal_3-1719988025394.png

If anyone knows this problem please replay. 
Thanks.

 

 

 

 

 

10 REPLIES 10
LCE
Principal

I'm using H735-DK's HyperRAM, and it must be initialized in memory-mapped mode before I touch any variables in the HypeRAM section.

So do you init HyperRAM before starting any RTOS stuff?

SofLit
ST Employee
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".freertos_data")));

This needs that the HypeRAM to be initialized before calling the main() i.e. in SystemInit()

I suggest to inspire from the OSPI initialization from STM32H735G-DK\Examples\OSPI\OSPI_HyperRAM_MemoryMapped example and implement it in direct access to the registers in SystemInit().

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I will Try, Thanks

by reading the registers of the octospi2 inside the main() function after the successful initialization of the hyperram / octospi ram using the MX_OCTOSPI2_Init() function auto generated from touchgfx generator (this code works normally), i found

//  EMPTY MEANS 0
  uint32_t octospi_cr_value = OCTOSPI2->CR; 		// 0x30000301
  uint32_t octospi_dcr1_value = OCTOSPI2->DCR1;		// 0x4170300
  uint32_t octospi_dcr2_value = OCTOSPI2->DCR2;		// 0x1
  uint32_t octospi_dcr3_value = OCTOSPI2->DCR3;		// 0x170000
  uint32_t octospi_dcr4_value = OCTOSPI2->DCR4;		// 0x190
  uint32_t octospi_sr_value = OCTOSPI2->SR;			// 0x2020
  uint32_t octospi_fcr_value = OCTOSPI2->FCR;		//
  uint32_t octospi_DLR_value = OCTOSPI2->DLR;		//
  uint32_t octospi_AR_value = OCTOSPI2->AR;			// 0x40cf8
  uint32_t octospi_DR_value = OCTOSPI2->DR;			//
  uint32_t value = OCTOSPI2->PSMKR;				//
   value = OCTOSPI2->PIR;				//
   value = OCTOSPI2->CCR;				// 0x2c003c00
   value = OCTOSPI2->TCR;				// 0x10000000
   value = OCTOSPI2->IR;					//
   value = OCTOSPI2->ABR;				//
   value = OCTOSPI2->LPTR;				//
   value = OCTOSPI2->WPCCR;				//
   value = OCTOSPI2->WPTCR;				//
   value = OCTOSPI2->WPIR;				//
   value = OCTOSPI2->WPABR;				//
   value = OCTOSPI2->WCCR;				// 0x2c003c00
   value = OCTOSPI2->WTCR;				//
   value = OCTOSPI2->WIR;				//
   value = OCTOSPI2->WABR;				//
   value = OCTOSPI2->HLCR;				//

 

these values do i need to set these values in the SystemInit() or do i need to set more like clock / GPIO if so where can i find that ?
@LCE 
@SofLit 

I'm not expert of that interface but you need to inspire from the example I provided previously and see how the registers were used and configured in the HAL. Don't forget to configure the GPIOs.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
LCE
Principal

I have no idea what touchgfx or Cube or HAL are doing, I set up HyperRam via the registers.

BUT I remember that I started with a working init for HyperRam in MM mode with a HAL setup from Cube.

Pavel A.
Evangelist III

@vishnu_illikkal The 2nd attempt was a good try... but it looks from the stack trace like C++ got you ))

There are some static TouchGFX things that initialize before main() and create FreeRTOS objects - which allocate from your new pool in hyperram.  But MX_OCTOSPI2_Init likely is called in your main() - which has not been run yet.

Now - if this guesswork is correct - you can easily fix it.

 

@Pavel A. 

Your guess is correct
1. I have started a fully working code using TouchGFX Designer

        It has TouchGFX working, FreeRTOS working and all needed stuff working
2. Currently the ucHeap of FreeRTOS is placed in RAM_D1 by default.
        I need to change this to External OSPI HyperRam

        This HyperRam is already setup and working properly in the project i created in step 1
3. When i try to move this to HyperRAM since it is not initialized untill the function  MX_OCTOSPI2_Init(); is called the HyperRAM becomes only available after this.
        But some FreeRTOS functions (see original post images) are trying to access the ucHeap even before the main() function is called.

       So it gives me a HardFault ErrorSo as per the suggestion of @SofLit  i am trying to initialize the OCTOSPI2 ram inside the SystemInit() function
      1. So I need to find the register values 
       2. i have read the various registers of the OCTOSPI2 from the working code from step 1

      3. Now what i need to know is what other registers do i need to set up for the OCTOSPI2 to work?
                 1. Like for example GPIO , Clock etc
                  2. Also how can i read the GPIO registers of the OCTOSPI2 pins?

vishnu_illikkal
Associate III

 

 

void SystemInit (void)
{
#if defined (DATA_IN_D2_SRAM)
 __IO uint32_t tmpreg;
#endif /* DATA_IN_D2_SRAM */

  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2)));  /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clock configuration to the default reset state ------------*/

   /* Increasing the CPU frequency */
  if(FLASH_LATENCY_DEFAULT  > (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)))
  {
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
	MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT));
  }

  /* Set HSION bit */
  RCC->CR |= RCC_CR_HSION;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, HSECSSON, CSION, HSI48ON, CSIKERON, PLL1ON, PLL2ON and PLL3ON bits */
  RCC->CR &= 0xEAF6ED7FU;

   /* Decreasing the number of wait states because of lower CPU frequency */
  if(FLASH_LATENCY_DEFAULT  < (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)))
  {
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
	MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(FLASH_LATENCY_DEFAULT));
  }

#if defined(D3_SRAM_BASE)
  /* Reset D1CFGR register */
  RCC->D1CFGR = 0x00000000;

  /* Reset D2CFGR register */
  RCC->D2CFGR = 0x00000000;

  /* Reset D3CFGR register */
  RCC->D3CFGR = 0x00000000;
#else
  /* Reset CDCFGR1 register */
  RCC->CDCFGR1 = 0x00000000;

  /* Reset CDCFGR2 register */
  RCC->CDCFGR2 = 0x00000000;

  /* Reset SRDCFGR register */
  RCC->SRDCFGR = 0x00000000;
#endif
  /* Reset PLLCKSELR register */
  RCC->PLLCKSELR = 0x02020200;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x01FF0000;
  /* Reset PLL1DIVR register */
  RCC->PLL1DIVR = 0x01010280;
  /* Reset PLL1FRACR register */
  RCC->PLL1FRACR = 0x00000000;

  /* Reset PLL2DIVR register */
  RCC->PLL2DIVR = 0x01010280;

  /* Reset PLL2FRACR register */

  RCC->PLL2FRACR = 0x00000000;
  /* Reset PLL3DIVR register */
  RCC->PLL3DIVR = 0x01010280;

  /* Reset PLL3FRACR register */
  RCC->PLL3FRACR = 0x00000000;

  /* Reset HSEBYP bit */
  RCC->CR &= 0xFFFBFFFFU;

  /* Disable all interrupts */
  RCC->CIER = 0x00000000;

#if (STM32H7_DEV_ID == 0x450UL)
  /* dual core CM7 or single core line */
  if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U)
  {
    /* if stm32h7 revY*/
    /* Change  the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
    *((__IO uint32_t*)0x51008108) = 0x000000001U;
  }
#endif

#if defined (DATA_IN_D2_SRAM)
  /* in case of initialized data in D2 SRAM (AHB SRAM) , enable the D2 SRAM clock (AHB SRAM clock) */
#if defined(RCC_AHB2ENR_D2SRAM3EN)
  RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);
#elif defined(RCC_AHB2ENR_D2SRAM2EN)
  RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN);
#else
  RCC->AHB2ENR |= (RCC_AHB2ENR_AHBSRAM1EN | RCC_AHB2ENR_AHBSRAM2EN);
#endif /* RCC_AHB2ENR_D2SRAM3EN */

  tmpreg = RCC->AHB2ENR;
  (void) tmpreg;
#endif /* DATA_IN_D2_SRAM */

#if defined(DUAL_CORE) && defined(CORE_CM4)
  /* Configure the Vector Table location add offset address for cortex-M4 ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = D2_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif /* VECT_TAB_SRAM */

#else

  /*
   * Disable the FMC bank1 (enabled after reset).
   * This, prevents CPU speculation access on this bank which blocks the use of FMC during
   * 24us. During this time the others FMC master (such as LTDC) cannot use it!
   */
  FMC_Bank1_R->BTCR[0] = 0x000030D2;

  /* Configure the Vector Table location add offset address for cortex-M7 ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = D1_AXISRAM_BASE  | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal AXI-RAM */
#else
  SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif

#endif /*DUAL_CORE && CORE_CM4*/


  /* our code */

  /* Enable clocks for GPIO ports used by OCTOSPI2 */
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOGEN;  // Enable GPIOG clock
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOFEN;  // Enable GPIOF clock

  /* Configure GPIOG */
  GPIOG->MODER = 0x6eabaf7a;
  GPIOG->OTYPER = 0;
  GPIOG->OSPEEDR = 0x33fcf0cf;
  GPIOG->PUPDR = 0;
  GPIOG->AFR[0] = 0xea000099;

  /* Configure GPIOF */
  GPIOF->MODER = 0xaeeffeaa;
  GPIOF->OTYPER = 0xc000;
  GPIOF->OSPEEDR = 0xa33003ff;
  GPIOF->PUPDR = 0x50000000;
  GPIOF->AFR[0] = 0x99999;

  /* Enable clock for OCTOSPI2 */
//    RCC->AHB3ENR |= RCC_AHB3ENR_OCTOSPI2EN;
  RCC->AHB3ENR = 0x284010;
  /* Configure and enable PLL2 for OCTOSPI */
  RCC->PLLCKSELR = 0x1905022; // PLL2M = 5, Source = HSE
  RCC->PLL2DIVR = 0x101084f; // PLL2N = 80, PLL2P = 2, PLL2Q = 2, PLL2R = 2
  RCC->PLLCFGR = 0x1ff031d; // PLL2 Range = 2, VCO = Wide
//    RCC->CR |= RCC_CR_PLL2ON; // Enable PLL2
  RCC->CR = 0x3f03c025;
  while ((RCC->CR & RCC_CR_PLL2RDY) == 0) {} // Wait until PLL2 is ready

  /* Set PLL2 as the clock source for OCTOSPI */
//    RCC->D1CCIPR = (RCC->D1CCIPR & ~RCC_D1CCIPR_OSPISEL_Msk) | RCC_D1CCIPR_OSPISEL_PLL2;
  RCC->D1CCIPR =  0x20;
  /* Initialize OCTOSPI2 with the values from the working project */
  OCTOSPI2->CR = 0;
  OCTOSPI2->DCR1 = 0x04170300;
  OCTOSPI2->DCR2 = 0x1;
  OCTOSPI2->DCR3 = 0x170000;
  OCTOSPI2->DCR4 = 0x190;
  OCTOSPI2->CCR = 0x2c003c00;
  OCTOSPI2->TCR = 0x10000000;
  OCTOSPI2->WCCR = 0x2c003c00;
  OCTOSPI2->CR = 0x30000301;

  /* Verify PLL settings */
//    RCC->PLLCKSELR = 0x1905022;
//    RCC->PLL2DIVR = 0x101084f;
//    RCC->PLLCFGR = 0x1ff031d;
//    RCC->CR = 0x3f03c025;
//    RCC->D1CCIPR =  0x20;

       uint32_t gpio1 = GPIOG->MODER;		// 0x6eabaf7a
       uint32_t	   gpio2 = GPIOG->OTYPER;		//
       uint32_t	   gpio3 = GPIOG->OSPEEDR;		// 0x33fcf0cf
       uint32_t	   gpio4 = GPIOG->PUPDR;			//
       uint32_t	   gpio5 = GPIOG->AFR[0];		// 0xea000099

	   uint32_t	   gpio11 = GPIOF->MODER;			// 0xaeeffeaa
	   uint32_t gpio22 = GPIOF->OTYPER;		// 0xc000
	   uint32_t   gpio33 = GPIOF->OSPEEDR;		// 0xa33003ff
	   uint32_t  gpio44 = GPIOF->PUPDR;			// 0x50000000
	   uint32_t  gpio55 = GPIOF->AFR[0];		// 0x99999

  /* our code */
}

 

 

I tried to write the registers with the values i read , now no HardFault error occurs but the code gets stcuk at startup_stm32h735xx.s file

 

 

/**
  ******************************************************************************
  * @file      startup_stm32h735xx.s
  * @author    MCD Application Team
  * @brief     STM32H735xx Devices vector table for GCC based toolchain. 
  *            This module performs:
  *                - Set the initial SP
  *                - Set the initial PC == Reset_Handler,
  *                - Set the vector table entries with the exceptions ISR address
  *                - Branches to main in the C library (which eventually
  *                  calls main()).
  *            After Reset the Cortex-M processor is in Thread mode,
  *            priority is Privileged, and the Stack is set to Main.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
    
  .syntax unified
  .cpu cortex-m7
  .fpu softvfp
  .thumb

.global  g_pfnVectors
.global  Default_Handler

/* start address for the initialization values of the .data section. 
defined in linker script */
.word  _sidata
/* start address for the .data section. defined in linker script */  
.word  _sdata
/* end address for the .data section. defined in linker script */
.word  _edata
/* start address for the .bss section. defined in linker script */
.word  _sbss
/* end address for the .bss section. defined in linker script */
.word  _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */

/**
 * @brief  This is the code that gets called when the processor first
 *          starts execution following a reset event. Only the absolutely
 *          necessary set is performed, after which the application
 *          supplied main() routine is called. 
 * @PAram  None
 * @retval : None
*/

    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler:  
  ldr   sp, =_estack      /* set stack pointer */

/* Call the clock system intitialization function.*/
  bl  SystemInit

/* Copy the data segment initializers from flash to SRAM */  
  movs  r1, #0
  b  LoopCopyDataInit

CopyDataInit:
  ldr  r3, =_sidata
  ldr  r3, [r3, r1]
  str  r3, [r0, r1]
  adds  r1, r1, #4
    
LoopCopyDataInit:
  ldr  r0, =_sdata
  ldr  r3, =_edata
  adds  r2, r0, r1
  cmp  r2, r3
  bcc  CopyDataInit
  ldr  r2, =_sbss
  b  LoopFillZerobss
/* Zero fill the bss segment. */  
FillZerobss:
  movs  r3, #0
  str  r3, [r2], #4
    
LoopFillZerobss:
  ldr  r3, = _ebss
  cmp  r2, r3
  bcc  FillZerobss
  
/* Call static constructors */
    bl __libc_init_array
/* Call the application's entry point.*/
  bl  main
  bx  lr    
.size  Reset_Handler, .-Reset_Handler

rest of the codes

 

 

Reset_Handler:

ldr sp, =_estack /* set stack pointer */ THIS IS THE LINE THAT STUCK