2020-04-01 11:55 AM
Hello,
I'm using an STM32F746 based board from EDT (http://www.edtc.com/sb_readmore.php?id=23), which can be selected as an application template in the TouchGFX Designer and start from there with the IAR toolchain.
I'm having troubles being able to perform operations on the internal flash (erase/read) after the initialization of touchgfx is done:
STM32F7DMA dma;
ETEM043005XDH6TouchController tc;
STM32F7Instrumentation mcuInstr;
#if !defined(USE_BPP) || USE_BPP==16
LCD16bpp display;
#elif USE_BPP==24
LCD24bpp display;
#else
#error Unknown USE_BPP
#endif
void touchgfx_init()
{
HAL& hal = touchgfx_generic_init<STM32F7HAL>(dma, display, tc, 480, 272, 0, 0);
os_inited = true;
#if !defined(USE_BPP) || USE_BPP==16
#ifdef SINGLE_FRAME_BUFFER_INTERNAL
//setup for single buffering
hal.setFrameBufferStartAddress((uint16_t*)frameBuf0, 16, false, false);
// The optimized strategy for single buffering requires the presence of a
// task delay function.
hal.registerTaskDelayFunction(&OSWrappers::taskDelay);
// Enable strategy.
hal.setFrameRefreshStrategy(HAL::REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL);
#else
//setup for double buffering.
hal.setFrameBufferStartAddress((uint16_t*)frameBuf0);
#endif
#elif USE_BPP==24
#ifdef SINGLE_FRAME_BUFFER_INTERNAL
#error Single frame buffer in internal is only possible in 16bpp due to memory constraints.
#endif
hal.setFrameBufferStartAddress((uint16_t*)frameBuf0, 24);
#else
#error Unknown USE_BPP
#endif
hal.setTouchSampleRate(2);
hal.setFingerSize(1);
// By default frame rate compensation is off.
// Enable frame rate compensation to smooth out animations in case there is periodic slow frame rates.
hal.setFrameRateCompensation(false);
// This platform can handle simultaneous DMA and TFT accesses to SDRAM, so disable lock to increase performance.
hal.lockDMAToFrontPorch(false);
mcuInstr.init();
//Set MCU instrumentation and Load calculation
hal.setMCUInstrumentation(&mcuInstr);
hal.enableMCULoadCalculation(true);
}
I am able to perform those operations if I don't call touchgfx_init(), which makes me think that there are some instructions in there that may be using the flash or maybe locking the HAL or something like that.
The code used to erase the sector first, and program it with dummy data is:
void main()
{
hw_init();
touchgfx_init()
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Erase the user Flash area
(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
/* Get the 1st sector to erase */
FirstSector = GetSector(ADDR_FLASH_SECTOR_7 );
/* Get the number of sector to erase from 1st sector*/
NbOfSectors = GetSector(FLASH_USER_END_ADDR) - FirstSector + 1;
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Sector = FirstSector;
EraseInitStruct.NbSectors = NbOfSectors;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
{
printf("Unable to erase sector\n");
}
printf("Sector erased :)\n");
uint16_t i;
HAL_StatusTypeDef status = HAL_ERROR;
Address = FLASH_USER_START_ADDR; //ADDR_FLASH_SECTOR_7
for(i = 0; i < 4; i++)
{
// #define DATA_32 ((uint32_t)0x12345678)
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32);
Address = Address + 4;
}
}
I have no clue how to find a solution for this since all the generated cpp code in the touchgfx is quite daunting to me (this is my first time working with embedded).
However, I've spent a good amount of time trying to debug it and I have noticed a few things that might help solving it:
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
0x8008498: 0x6ea1 LDR R1, [R4, #0x68]
0x800849a: 0x68c8 LDR R0, [R1, #0xc]
0x800849c: 0x68c5 LDR R5, [R0, #0xc]
This is the instruction that's raising the exception as the fault exception viewer says.
If I can provide anything else of use, please let me know. Thank you so much for reading.
PS: I'll also leave the code of the hw_init() function which is also auto-generated.
void hw_init()
{
HAL_Init();
SystemClock_Config(); //200MHz overdrive, FL6
/* Initialize the QSPI */
BSP_QSPI_Init();
BSP_QSPI_MemoryMappedMode();
HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
#ifndef SINGLE_FRAME_BUFFER_INTERNAL
BSP_SDRAM_Init();
#endif
BSP_LCD_Init();
BSP_LCD_LayerInit(0, frameBuf0);
BSP_LCD_DisplayOn();
MX_TIM12_Init();
#ifndef SIMULATOR
//MX_USART2_UART_Init();
MX_USART6_UART_Init();
//MX_I2C_Init();
//MX_SPI5_Init();
MX_GPIO_Init();
#endif
GPIO::init();
SCB_EnableDCache();
SCB_EnableICache();
//Enable CRC engine for STM32 Lock check
__HAL_RCC_CRC_CLK_ENABLE();
/* Configure unused area of QSPI region as strongly ordered.
* This is *important* to avoid unintentional fetches from illegal
* addresses due to cache/speculation which would halt the MCU.
*/
HAL_MPU_Disable();
MPU_Region_InitTypeDef MPU_InitStruct;
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes as WT for QSPI (used 16Mbytes) */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB; /* NOTE! Change this if you change QSPI flash size! */
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
//Deactivate speculative/cache access to first FMC Bank to save FMC bandwidth
FMC_Bank1->BTCR[0] = 0x000030D2;
}
2020-04-02 04:56 AM
I think I've solve it by programming the flash in another task and not in main. However, could anyone point me which is the role that would play having an MPU initialization for the flash region? Like so:
// MPU FOR SECTOR 7 OF FLASH
MPU_InitStruct.BaseAddress = 0x080C0000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
I've done it now but I'm not sure if it's making any difference.