2022-04-01 07:16 PM
Hi,
I created a project for the Tiny Shark using TouchGFX 1.17 and found it generated code for the NOR Ram OCTOSPI interface that was incorrect such that a Hard Fault was generated.
I built another project using Ver. 1.18 and had the same problem.
Luckily i put a tag next to the modded line so I found it in the earlier project and put it into the new one.
The relevant code is:
/**
* @brief OCTOSPI1 Initialization Function
* @param None
* @retval None
*/
static void MX_OCTOSPI1_Init(void)
{ uint32_t statusResult;
/* OCTOSPI1 parameter configuration*/
hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 1;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
hospi1.Init.DeviceSize = 26;
hospi1.Init.ChipSelectHighTime = 2;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi1.Init.ClockPrescaler = 3;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi1.Init.ChipSelectBoundary = 0;
hospi1.Init.ClkChipSelectHighTime = 0;
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi1.Init.MaxTran = 0;
hospi1.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
/* OCTOSPI1_Init 2 */
BSP_OSPI_NOR_Init_t Flash;
Flash.InterfaceMode = BSP_OSPI_NOR_OPI_MODE;
Flash.TransferRate = BSP_OSPI_NOR_DTR_TRANSFER;
hospi_nor->Instance = hospi1.Instance; /* rjg mod <==========================*/
BSP_OSPI_NOR_DeInit(0);
int32_t RetVal = BSP_OSPI_NOR_Init(0, &Flash);
if(RetVal != BSP_ERROR_NONE)
{
Error_Handler();
}
RetVal = BSP_OSPI_NOR_EnableMemoryMappedMode(0);
if(RetVal != BSP_ERROR_NONE)
{
Error_Handler();
}
}
Without the additional line I added a null handle is passed into following functions giving a hard error.
I'm not sure whether I have fixed the problam in the best way as I'm only an amateur programmer and my teacher knew less than I did. You can guess who my teacher was.
Has anyone else come across this?
I hope this is useful to someone else.
Regards
Rob
Solved! Go to Solution.
2022-05-09 10:33 AM
>>Has anyone else come across this?
Encountered similar.
More like hospi_nor global is poorly initialized, or ordering of things is out of sequence. Ideally there should be asserts, or NULL check in BSP_SPI_NOR_DeInit() to catch some of this before it faults.
Watch in things like the External Loader that global statics are not initialized by code that would have been in startup.s or scatterloader.. If SystemInit() is being used correctly, this also often exists in a pre-initialization state, as it is supposed to set the system's memories up prior to the C Runtime initializing there content.
2022-05-09 08:59 AM
Hello @Garnett.Robert,
Can you please confirm my understanding regarding your problem:
Thanks.
Chahinez.
2022-05-09 10:33 AM
>>Has anyone else come across this?
Encountered similar.
More like hospi_nor global is poorly initialized, or ordering of things is out of sequence. Ideally there should be asserts, or NULL check in BSP_SPI_NOR_DeInit() to catch some of this before it faults.
Watch in things like the External Loader that global statics are not initialized by code that would have been in startup.s or scatterloader.. If SystemInit() is being used correctly, this also often exists in a pre-initialization state, as it is supposed to set the system's memories up prior to the C Runtime initializing there content.
2022-05-09 10:44 AM
Yes, random, unchecked use of global hospi_nor in BSP_OSPI_NOR_DeInit(), structure initialized with zero
Used Here - OSPI_NOR_MspDeInit()
And Here - HAL_OSPI_DeInit()
Similarly Here
HAL_OSPI_DeInit() NULL checks the hospi pointer, but not hospi->Instance
So
a) HAL_OSPI_DeInit() should catch this and error
b) BSP_OSPI_NOR code should initialize its structures
/* Check the OSPI handle allocation */
if ((hospi == NULL) || (hospi->Instance == NULL)) // cheap test, evaluated left to right
...
2022-05-10 08:39 PM
Hi TDL,
It does appear to be random as the unmodified code did work, but after adding more peripheral inits and other stuff the problem cropped up again. Luckily I remembered the problem and had flagged it with a comment /* rjg mod */ so i was able to fix it. I'm not happy with the fix. I think there is some problem which is obscure to me.
It wasn't an easy problem to find, that's why I put it in the forum.
Best regards
Rob
2022-05-10 11:07 PM
Yes
That is correct. See Tesla DeLorean's reply to your reply.
I always use the ITCM for code and what I do in make this memory read-only with the MPU so if I try to write to this memory I get a memory protection fault. Very easy to debug.
Essentially the handle doesn't get set and the code eventually addresses memory at 0x00000000 and if it tries to write to this or related addresses in the handle fields structure I get an MPU fault.
I don't know what the correct fix should be.
Best regards
Rob