The short answer is no, the Cortex-M0 does not always default the program counter to 0x0 when an interrupt triggers. The actual default address depends on the specific interrupt triggered and how the interrupts are configured.
Overview of Cortex-M0 Interrupts
The Cortex-M0 processor has several different kinds of interrupts that can be triggered by external events or internal exceptions. These include:
- External interrupts – Triggered by external signals like GPIO pins
- Internal exceptions – Triggered by events inside the processor like illegal opcode execution
- Software interrupts – Triggered explicitly by software
- System exceptions – Includes reset, NMI, and hard fault
When an interrupt is triggered, the processor stops normal program execution and jumps to an interrupt handler function. The address of this handler function is called the interrupt vector.
On the Cortex-M0, there are three main ways interrupt vectors can be configured:
- Fixed default locations – The processor has preset vector locations for each interrupt
- Vector table – A table of interrupt vectors defined by the application
- Vector address register – A register that holds the address of the interrupt handler
Fixed Default Vector Locations
The Cortex-M0 has a set of fixed default vector locations built into the processor hardware. These include:
- Reset – 0x00000004
- NMI – 0x00000008
- HardFault – 0x0000000C
- SVCall – 0x0000002C
- PendSV – 0x00000038
- SysTick – 0x0000003C
So anytime one of these fixed system exceptions occur, the processor will jump to the hardcoded vector address for that exception. For example, a reset will always go to 0x00000004.
Vector Table
The Cortex-M0 also allows for an interrupt vector table to be defined by the application firmware. This table contains entries for each enabled interrupt, specifying the address of the corresponding interrupt handler function.
The vector table start address is configured by setting the VTOR register. The processor fetches the vector addresses sequentially from this table when interrupts occur.
Using the vector table allows interrupts to be remapped from their default handlers. For example, the reset handler could be remapped to a different address besides the default 0x00000004.
Vector Address Register
The NVIC (Nested Vectored Interrupt Controller) in the Cortex-M0 contains vector address registers for external interrupts and system exceptions. These registers allow the interrupt vector to be dynamically changed in software.
For external interrupts, there is one vector address register per interrupt. So INT_0’s vector can be configured separately from INT_1, etc. This allows flexibility in handling multiple external interrupts.
For system exceptions like memory faults, there is a single vector address register. So all system faults would share the same configured handler function.
When Does the Cortex-M0 Default to 0x0?
Based on the different interrupt vector configurations, the Cortex-M0 will only default the program counter to 0x0 for a specific subset of interrupts:
- Reset always goes to 0x00000004
- Exceptions go to 0x0000000C, 0x0000002C, etc. based on the specific exception
- External interrupts depend on vector table or address register configuration
- Software interrupts jump to the address passed to the svc instruction
The main times 0x0 is used as the default vector are:
- When no vector table is configured and interrupts aren’t enabled. The processor has nowhere to jump to.
- When an unused interrupt occurs without a handler configured.
So in summary, the Cortex-M0 only defaults to 0x0 in limited cases:
- No vector table defined
- Specific interrupt not enabled/configured
Typically real applications would have a vector table configured, so interrupts would jump to non-zero handler addresses instead of defaulting to 0x0.
Typical Interrupt Handling Work Flow
Here is a typical work flow for handling interrupts on the Cortex-M0:
- Define interrupt handler functions for each interrupt needed
- Create a vector table with entries pointing to the handlers
- Configure VTOR to point to the vector table base address
- Enable interrupts using the NVIC
- Write handlers to save context, clear interrupt, handle event, restore context
- Set interrupt priorities using the NVIC
- Enable desired interrupts globally using the NVIC
Following this work flow prevents interrupts from defaulting to 0x0 and instead redirects them to handler functions.
Reset Behavior
It is worth calling out reset specifically, since it is a common source of confusion around default vectors.
On Cortex-M0 reset:
- Program counter goes to 0x00000004 always
- Main stack pointer initialized to end of RAM
- Processor executes reset handler pointed to by 0x00000004
The reset handler then typically copies data from flash to RAM, zeros out .bss, and calls main().
Debugging Interrupt Issues
Some tips for debugging unexpected interrupt behavior on Cortex-M0:
- Double check vector table configuration and addresses
- Verify desired interrupts enabled in NVIC
- Set breakpoint at default handler 0x0 to see which interrupt hits it
- Examine stack on exception to identify exception number
- Check return address to see where interrupt originated
Debugging and tracing tools like embedded trace macrocells (ETM) are very useful for analyzing interrupts. The interrupt statistics features built into many Cortex-M0 chips are also quite helpful.
Conclusion
In summary, the Cortex-M0 does not always reset the program counter to 0x0 on interrupts. The default behavior depends on the interrupt source and vector configuration.
Using the vector table and NVIC properly allows interrupts to be handled by dedicated handler functions instead of defaulting to 0x0. This allows robust interrupt processing in Cortex-M0 applications.
With good configuration and debugging techniques, developers can leverage the flexible and powerful interrupt capabilities of the Cortex-M0 in their embedded designs.