Hi,
We are a team of 3 developers, and i had a project using your example "flash_partitioning_s32k146" working well. We have a S32K146_100 pins, 16 MHZ clock in our project. Others component already presents were : canCom1:flexcan, intMan1:interrut_manager, watchdog1:wdog and clockMan1:clock_manager which i already talk about.
And my collegue just added somes components, such as: lpit1:lpit, pdb0:pdb, adCinv0:adc, trgmux1:trgmux, flexTimer_Task:ftm_mc and flexTimer_pwm1:ftm_pwm.
Somehow, something is broken now. And it throw a DefaultISR after i try to do
void vInitFlashMemory()
{
status_t ret; /* Store the driver APIs return code */
/* Install interrupt for Flash Command Complete event */
INT_SYS_InstallHandler(FTFC_IRQn, CCIF_Handler, (isr_t*) 0);
INT_SYS_EnableIRQ(FTFC_IRQn);
/* Enable global interrupt */
INT_SYS_EnableIRQGlobal();
/* Always initialize the driver before calling other functions */
FLASH_DRV_Init(&FlashEEPROM_InitConfig0, &flashSSDConfig);
/* Config FlexRAM as EEPROM if it is currently used as traditional RAM */
if (flashSSDConfig.EEESize == 0u)
{
#ifndef FLASH_TARGET
/* First, erase all Flash blocks if code is placed in RAM to ensure
* the IFR region is blank before partitioning FLexNVM and FlexRAM */
ret = FLASH_DRV_EraseAllBlock(&flashSSDConfig);
DEV_ASSERT(STATUS_SUCCESS == ret);
/* Verify the erase operation at margin level value of 1 */
ret = FLASH_DRV_VerifyAllBlock(&flashSSDConfig, 1u);
DEV_ASSERT(STATUS_SUCCESS == ret);
#endif
/* Configure FlexRAM as EEPROM and FlexNVM as EEPROM backup region,
* DEFlashPartition will be failed if the IFR region isn't blank.
* Refer to the device document for valid EEPROM Data Size Code
* and FlexNVM Partition Code. For example on S32K144:
* - EEEDataSizeCode = 0x02u: EEPROM size = 4 Kbytes
* - DEPartitionCode = 0x08u: EEPROM backup size = 64 Kbytes */
ret = FLASH_DRV_DEFlashPartition(&flashSSDConfig, 0x02u, 0x08u, 0x0u, false, true);
/* Re-initialize the driver to update the new EEPROM configuration */
ret = FLASH_DRV_Init(&FlashEEPROM_InitConfig0, &flashSSDConfig);
}
/* Make FlexRAM available for EEPROM */
ret = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, &EEPROM_status);
}
It goes inside FLASH_DRV_EraseAllBlock function, then FLASH_DRV_CommandSequence, and at the end of the function throw a <signal handler called>() at 0xfffffff9
Which give me on View Disassembly ( i dunno if it's help)
fffffff1: movs r0, r0
fffffff3: movs r0, r0
fffffff5: movs r0, r0
fffffff7: movs r0, r0
fffffff9: Unable to retrieve disassembly data from backend.
I have set in my linker a RAM0 bloc m_data_RAM0:
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x00000400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000400;
/* If symbol __flash_vector_table__=1 is defined at link time
* the interrupt vector will not be copied to RAM.
* Warning: Using the interrupt vector from Flash will not allow
* INT_SYS_InstallHandler because the section is Read Only.
*/
M_VECTOR_RAM_SIZE = DEFINED(__flash_vector_table__) ? 0x0 : 0x0400;
/* Specify the memory areas */
MEMORY
{
/* Flash */
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0006FBF0
ROM_CALIBRATION (RW) : ORIGIN = 0x00070000, LENGTH = 0x0000F000 /* 60k */
/* data_flash */
eeprom_dat (RW) : ORIGIN = 0x10008000, LENGTH = 0x00001000 /* 4K */
/* SRAM_L */
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00008000 /* 32k */
m_data_2 (RW) : ORIGIN = 0x1FFF8000, LENGTH = 0x00004000 /* 16k */
m_data_RAM0 (RW) : ORIGIN = 0x1FFFC000, LENGTH = 0x00004000 /* 16k */
/* SRAM_U */
RAM_CALIBRATION (RW) : ORIGIN = 0x20000000, LENGTH = 0x0000F000 /* 60k */
}
With .SRAM0 defined as:
.SRAM0 ORIGIN(m_data_RAM0) :/*6K*/
{
. = ALIGN(4);
KEEP(*(.SRAM0)) /* Keep section even if not referenced. */
. = ALIGN(4);
} > m_data_RAM0
And defined two functions as in the example:
void CCIF_Handler(void);
/* If target is flash, insert this macro to locate callback function into RAM */
void CCIF_Callback(void) __attribute__((section (".SRAM0")));
/*!
\brief Interrupt handler for Flash Command Complete event
*/
void CCIF_Handler(void)
{
/* Disable Flash Command Complete interrupt */
FTFx_FCNFG &= (~FTFx_FCNFG_CCIE_MASK);
return;
}
/*!
\brief Callback function for Flash operations
*/
void CCIF_Callback(void)
{
/* Enable interrupt for Flash Command Complete */
if ((FTFx_FCNFG & FTFx_FCNFG_CCIE_MASK) == 0u)
{
FTFx_FCNFG |= FTFx_FCNFG_CCIE_MASK;
}
}
I am compiling with GCC.
If i look at my .map file i have:
.SRAM0 0x1fffc000 0x7c
0x1fffc000 . = ALIGN (0x4)
*(.SRAM0)
.SRAM0 0x1fffc000 0x30 ./Sources/EEPROM/EEPROM_manager.o
0x1fffc000 CCIF_Callback
.SRAM0 0x1fffc030 0x4a ./Sources/CAN/Com/App_Com.o
0x1fffc07c . = ALIGN (0x4)
*fill* 0x1fffc07a 0x2
Do you have any ideas, about what could have broke the project and give me this issue ? I am searching for a week now, and i am running out of ideas of where to look.
I have read some topics from other projects, which are saying that the Vector table must be in RAM too for some cases, as VTOR, but i don't know how to do that.
Best regards,
Brice
已解决! 转到解答。
I'm confused now. Is the project executed from RAM or from flash? If you run it from flash,it doesn't make sense to run FLASH_DRV_EraseAllBlock command because it will erase everything and even if FLASH_DRV_EraseAllBlock runs from RAM, there's no code you can return to.
Because there's
#ifndef FLASH_TARGET
... it should be executed only when the project is running from RAM using the debugger.
Regards,
Lukas
Hi Brice,
isn't that caused by read-while-write error? Is there any interrupt that could be triggered during the erase the operation while its handler accesses that flash block? As a first step, I would try to disable all interrupts before calling the erase function.
Regards,
Lukas
Hi,
Thanks for your answer. I tried to disable interrupts but it was not the issue.
At the end we have just removed EraseAllBlock and VerifyAllBlock function, and the program seems to run. I didn't tested so much right now, so maybe theses functions are not needed.
About read-while-write, we didn't defined asynchrones functions and this part of the code is almost at the top of the main.c, just after Clock initialisation. So it should not have this kind of issues i guess ?
Best regards,
I'm confused now. Is the project executed from RAM or from flash? If you run it from flash,it doesn't make sense to run FLASH_DRV_EraseAllBlock command because it will erase everything and even if FLASH_DRV_EraseAllBlock runs from RAM, there's no code you can return to.
Because there's
#ifndef FLASH_TARGET
... it should be executed only when the project is running from RAM using the debugger.
Regards,
Lukas
Hi Lukas,
It was in FLASH configuration yes.
I am a bit confused too, so if i understood, FLASH_DRV_EraseAllBlock will Erase P-Flash, D-Flash and EERAM, and if the code isn't in RAM, it will be erased, meaning we erased ourself and lead to a Hardfault error with memory RAM error.
But if the code is in RAM it can return to the RAM and keep being executed. What i don't get is why it was working the first time when we didn't used RAM configuration.
I have another question, from where are executed FLASH_DRV_EraseSector and FLASH_DRV_EraseAllBlock ? It depend of theses lines ?
.code : AT(__CODE_ROM)
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
. = ALIGN(4);
__code_end__ = .; /* Define a global symbol at code end. */
__code_ram_end__ = .;
} > m_data
__CODE_END = __CODE_ROM + (__code_end__ - __code_start__);
__CUSTOM_ROM = __CODE_END;
or with RAM configuration
/* Section for storing functions that needs to execute from RAM */
.code_ram :
{
. = ALIGN(4);
__CODE_RAM = .;
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
__CODE_ROM = .; /* Symbol is used by start-up for data initialization. */
__CODE_END = .; /* No copy */
__code_ram_end__ = .;
. = ALIGN(4);
} > m_text
__etext = .; /* Define a global symbol at end of code. */
__DATA_ROM = .; /* Symbol is used by startup for data initialization. */
__DATA_END = __DATA_ROM; /* No copy */