I am trying to use flash memory in a KM14 processor but the processor resets when I attempt to erase a sector. I have used the FTFA driver from the MKM Bare Metal Software Drivers, and I have the same problem when I port the Processor Expert FLASH_LDD component. As far as I have been able to work out, the crash occurs when the code executes the FTFA_ExecCmd() code (Bare Metal version) or SafeRoutine() code (PE version). AFAIK these routines execute from RAM. As far as I have been able to work out the processor enters the hardfault_ISR code (though after the reset the RCM_SRS1 register shows ARM Core LOCKUP as the reset reason - possibly because subsequent errors happen while in the hardfault_ISR loop).
1 Sometimes the sector is erased and sometimes it is not erased.
2 The write (4 bytes) to flash operations work correctly, without the reset, even though these use the same FTFA_ExecCmd() or SafeRoutine() code.
AFAIK memory protection is off, in both the MPU_CESR and FPROT registers. The watchdog timer is off. I am using FreeRTOS with taskENTER_CRITICAL() and taskEXIT_CRITICAL() around the FTFA_ExecCmd() or SafeRoutine() code. Using taskDISABLE_INTERRUPTS() and taskENABLE_INTERRUPTS() makes no difference.
I have used the same Processor Expert FLASH_LDD component without problems KL05 and KL15 processors.
What is causing the reset and how do I fix it?
I don't see that the "KM34Z256 flash erase sector problem" post is relevant. I don't have NMIs enabled and am not getting NMIs. my FOPT = 0xF3 showing NMIs are disabled.
I am looking for an explanation for why executing the FTFA_ExecCmd() code crashes when the command is Erase Sector but not when it is Write Longword. Is it related to the time it takes to execute, or the power requirements, or stability of code executing in SRAM? Or what?
Regards - Charles
understood. Can you please try to run ftfa_test example from KM128SWDRV_R4_1_5 drivers? If you have already tried and found it also fails was the project imported properly by the tool-chain without any warnings?
If you run any interrupts in parallel with flash commands then use DisableInterrupts () ... EnableInterrupts() macros to block them during execution of the flash state machine. Provided you use portDISABLE_INTERRUPTS() ... portENABLE_INTERRUPTS() please note that these functions were modified in BM DRV not to disable all interrupts but only these that calls FreeRTOS API functions - for more details refer to freertos_cfg.h file in the BM DRV project.
It is indeed the interrupts causing the problem. If I bracket _FTFA_ExeceCmd() with DisableInterrupts() and EnableInterrupts() then all is well.If I use taskDISABLE_INTERRUPTS() and taskENABLE_INTERRUPTS() then it crashes.
Note that the Processor Expert code uses taskDISABLE_INTERRUPTS() and taskENABLE_INTERRUPTS().
You should flag this issue more clearly - it has taken me almost 2 days to find and fix and document...
Regards - Charles
you can use still taskDISABLE_INTERRUPTS() and taskENABLE_INTERRUPTS() but let know FreeRTOS which interrupts shall be controlled by these two macros - update #define configSYSCALL_INTERRUPT_MASK ... in freertos_cfg.h.
The standard behavior of FreeRTOS kernel for Cortex-M0+ core has been modified to allow all interrupts not calling FreeRTOS API functions to execute without blocking and we have used this functionality for software high-resolution/low-jitter pulse output generation used in an energy power meter application.
Hi Martin - could you check if I understand this correctly?
Tracing through the Processor Expert and KM34 Bare Metal Drivers freertos_config.h files, I think that in PE taskDISABLE_INTERRUPTS() results in a “cpsid i” instruction that disables (all) interrupts, but in the KM34 Bare Metal drivers taskDISABLE_INTERRUPTS() results in *(portNVIC_ICER) = configSYSCALL_INTERRUPT_MASK (disable interrupts on a case-by-case basis). By default configSYSCALL_INTERRUPT_MASK = 0, so no interrupts are disabled.
The (well-hidden) comment says:
/* The configSYSCALL_INTERRUPT_MASK defines masks of all interrupts that call */
/* FreeRTOS API functions. Select zero or one or more OR’ed interrupt masks: */
In other words you suggest users set a value for configSYSCALL_INTERRUPT_MASK but the default is
“don’t disable any interrupts”. It would be safer if the default was "disable all interrupts".
Regards - Charles
your understanding is correct.
If you prefer controlling all interrupts by default in any new projects created using make_project.exe utility, just please go to the KM128SWDRV_R4_1_5\template subfolder and make the following change in freertos_cfg.h file:
#define configSYSCALL_INTERRUPT_MASK 0xffff
Please refer to pittask_test project for more details on how to leverage this capability. In this particular project pit_callback (routine called by PIT timer interrupt) calls FreeRTOS API functions and therefore must be controlled by the RTOS kernel. Therefore configSYSCALL_INTERRUPT_MASK in freertos_cfg.h file is set as follows:
#define configSYSCALL_INTERRUPT_MASK configPITx_INT
On the contrary to PIT timer interrupt, any other potential interrupts programmed in the same code in bare-metal fashion and not calling FreeRTOS functions will execute without RTOS interference.
I have investigated this subject again and decided to change to disable / enable all interrupts instead of masking interrupts in NVIC registers in next release of KM34 Bare Metal Drivers. Modified files will be included in R4_1_6 release together with new peripheral macros and one bug fixed in the ADC driver.