I wanted to post this on the off chance it helps a neophyte like me dealing with the same problem. My main method looks something like this:
int main() {
USBDriver usb();
// Make some tasks
vTaskStartScheduler();
}
usb responds to interrupts and buffers the results into circular buffers. A task polls these buffers periodically. After the scheduler starts, one of these interrupts fires and a INVSTATE hard fault gets thrown.
Investigating the problem, I first suspected something with the interrupts. No luck. Then I noticed that parts of the usb object were becoming corrupted. Finally, I landed on the forum post below: (can’t link it, but you should be able to search with the partial)
Yep, that is a documented part of the Cortex-Mx ports. (and perhaps some other ports), the “main” stack is reset and reused as the ISR stack, so your setup code should not put objects on the main stack. Make the static or global objects.
Thanks for adding some context. I am probably blind, but where is this documented? I’d like to check there in case there are some other things I missed.
Cortex-M MCUs have a main stack (MSP register) and a process stack (PSP register). The latter is used for tasks stack managed by FreeRTOS. The main stack is used by ISRs.
You create the USBDriver instance on the main stack and start FreeRTOS.
Hence the object living in the main stack might and likely will be corrupted as soon as an ISR runs.
Hence make the instances e.g. global or static as mentioned before to avoid their corruption.
Edit. This is also found multiple times in the forum and few instances here:
This is great. Thank you for the additional information. I focused mainly on the Debugging Hard Fault & Other Exceptions page and the Running the RTOS on a ARM Cortex-M Core page when I was trying to debug this. I humbly suggest that 3. mentioned by hs2 be added to the debugging hard fault page.