FLASH (rwx): ORIGIN = 0x60000000, LENGTH = 7936K
ERAM (rwx): ORIGIN = 0x70000000, LENGTH = 16384K
SCB_MPU_RBAR = 0x60000000 | REGION(i++); // QSPI Flash
SCB_MPU_RASR = MEM_CACHE_WBWA | READONLY | SIZE_16M;
SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_16M;
Question now is, is 1.7s freeze related with use of PSRAM or with doubling (or 'wrong'/huge size) in startup.c ?The QSPI pads for PSRAM on the bottom are mapped to the MCU with those FlexSPI2 commands for MPU (protection ) control. Their privilege's and purpose.
In Doom, yes, it uses PSRAM (but I don't think it's used in the menu, where the freeze happened) and the doubling was problem.Question now is, is 1.7s freeze related with use of PSRAM or with doubling (or 'wrong'/huge size) in startup.c ?
Good question. Let's wait what Udo says.IOW, do all freeze code use PSRAM?
Yes and yes. If there are accesses by the hardware (i.e. DMA) you need the same cache handling as with DMAMEM.Is access to PSRAM cached?,
does this cache then be cleared as with DMAMEM?
Well, I guess we should still be a little cautious, because we have seen before that there can be many hours between Freezes and therefore I assume, we could only safely call this issue resolved, after we understood, why not only Frank's solution but also disabling any use of USBSerial are/were fixes.
SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2
SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_32M;
BTW: Does the 'fix' in startup.c break anything else?
@Paul:
Is this correct (?)
The 2nd has higher priority - so the first is not active. But can the MPU handle this correctly?Code:SCB_MPU_RBAR = [COLOR=#00ff00]0x70000000[/COLOR] | REGION(i++); // FlexSPI2 SCB_MPU_RASR = MEM_CACHE_WBWA | [COLOR=#00ff00]READONLY[/COLOR] | NOEXEC | SIZE_256M; SCB_MPU_RBAR =[COLOR=#00ff00] 0x70000000 [/COLOR]| REGION(i++); // FlexSPI2 SCB_MPU_RASR = MEM_CACHE_WBWA | [COLOR=#00ff00]READWRITE [/COLOR]| NOEXEC | SIZE_16M;
Don't want produce the next false positive here...take this with care: Doom is running for 30minutes now, with the first commented.-out, and without freeze. That's unusual..
I'm just surfing the thread, but: has anyone verified that those SCB_MPU register writes 1) are emitted by the compiler without any reordering, and 2) are actually executed by the CPU in the specified order?
All of the references to different behavior with different GCC versions and optimization levels make me nervous. It seems like write barriers are needed in more places than ever, as the CPU designers and compiler maintainers get more desperate in their search for optimization opportunities. Just declaring stuff volatile doesn't work so well anymore.
Can anyone who experienced this problem please give 1.54-beta9 a try?
https://forum.pjrc.com/threads/67252-Teensyduino-1-54-Beta-9
This latest beta includes Frank's fix. It also supports Arduino 1.8.15, though the fix applies to all supported Arduino versions.
Would be nice to just double check this bug really is fixed before the upcoming 1.54 release.
#if !defined SERIALEVENTRUN_H_DEFINED
#define SERIALEVENTRUN_H_DEFINED
void SerialEventRun(void) __attribute__((weak));
void USBHostEvent(void) __attribute__((weak));
bool USBHost_available() __attribute__((weak));
void SerialEvent() __attribute__((weak));
void SerialEvent1() __attribute__((weak));
void SerialEvent2() __attribute__((weak));
void SerialEvent3() __attribute__((weak));
void SerialEvent4() __attribute__((weak));
void SerialEvent5() __attribute__((weak));
void SerialEvent6() __attribute__((weak));
void SerialEvent7() __attribute__((weak));
void SerialEvent8() __attribute__((weak));
void SerialUSBEvent1() __attribute__((weak));
void SerialUSBEvent2() __attribute__((weak));
void SerialEventRun(void) {
if (SerialEvent
&& Serial
&& Serial.available() > 0) {
SerialEvent();
}
if (SerialEvent1
&& Serial1
&& Serial1.available() > 0) {
SerialEvent1();
}
if (SerialEvent2
&& Serial2
&& Serial2.available() > 0) {
SerialEvent2();
}
if (SerialEvent3
&& Serial3
&& Serial3.available() > 0) {
SerialEvent3();
}
if (SerialEvent4
&& Serial4
&& Serial4.available() > 0) {
SerialEvent4();
}
if (SerialEvent5
&& Serial5
&& Serial5.available() > 0) {
SerialEvent5();
}
if (SerialEvent6
&& Serial6
&& Serial6.available() > 0) {
SerialEvent6();
}
if (SerialEvent7
&& Serial7
&& Serial7.available() > 0) {
SerialEvent7();
}
if (SerialEvent8
&& Serial8
&& Serial8.available() > 0) {
SerialEvent8();
}
if (USBHostEvent
&& USBHost_available()) {
USBHostEvent();
}
#if !defined TEENSY_DEBUG
#if defined USB_DUAL_SERIAL || defined USB_TRIPLE_SERIAL
if (SerialUSBEvent1
&& SerialUSB1
&& SerialUSB1.available() > 0) {
SerialUSBEvent1();
}
#endif
#if defined USB_TRIPLE_SERIAL
if (SerialUSBEvent2
&& SerialUSB2
&& SerialUSB2.available() > 0) {
SerialUSBEvent2();
}
#endif
#endif
}
#endif
Are you using serialEvents? There is an issues, at least with the Teensy 4.1 where serialEvents may recurse due to the invocation of "yield()" from within the Serial API's. This can result in lockups.
I worked around this by reimplementing the serialEvents through the following header file:
...
Rename your serialEvent functions to SeriaEvent, and call SerialEventRun() at the end of your loop() function.
Patrick