2024-07-02 11:27 PM
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:
heap_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
If anyone knows this problem please replay.
Thanks.
2024-07-03 03:32 AM
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?
2024-07-03 06:47 AM
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().
2024-07-03 10:30 PM
I will Try, Thanks
2024-07-10 05:53 AM
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
2024-07-10 06:05 AM
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.
2024-07-10 06:14 AM
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.
2024-07-10 06:19 AM - edited 2024-07-10 06:21 AM
@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.
2024-07-10 09:45 PM
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?
2024-07-11 12:55 AM
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>© 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