SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Cortex-m0 interrupt_demo simulation issue
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

Cortex-m0 interrupt_demo simulation issue

Neil Salmon
Last updated: September 16, 2023 9:27 am
Neil Salmon 6 Min Read
Share
SHARE

The Cortex-M0 processor from ARM is one of the most popular 32-bit embedded processors used in various microcontroller units (MCUs) and system-on-chips (SoCs). As an ultra-low power processor, it is well-suited for resource constrained and battery operated devices. One of the key features of Cortex-M0 is its interrupt handling mechanism which allows efficient asynchronous processing of events. However, enabling and properly configuring interrupts on Cortex-M0 requires good understanding of the processor architecture and programming model.

Contents
Interrupt Handler Not RegisteredInterrupt Not EnabledSysTick Timer Not StartedPriority MaskingFault ExceptionsDebug HaltingRace Condition with Main LoopImproper Simulation ModelConclusion

A common issue developers face when starting to work with Cortex-M0 interrupts is getting the ‘interrupt_demo’ code example to work properly in simulation. The interrupt_demo example demonstrates registering a handler for the SysTick timer interrupt and toggling an LED upon interrupt assertion. However, the LED toggle is often not observed in simulation even when the SysTick interrupt is triggered. There are a few reasons why this issue may occur:

Interrupt Handler Not Registered

The first step in enabling any interrupt on Cortex-M0 is to register an interrupt handler. This is done by populating the vector table with a function pointer for the specific interrupt. For SysTick, the vector number is 15 so the following code is used:

void SysTick_Handler(void) {
  // toggle LED
}

void (*vector_table[16])(void) = {
  //...
  SysTick_Handler // entry 15 for SysTick
};  

If the interrupt handler is not registered properly in the vector table, the processor will not know which function to execute when the SysTick interrupt occurs. Double check that the right vector table index is used and the function name matches the handler.

Interrupt Not Enabled

After registering the interrupt handler, the next step is to enable the SysTick interrupt in the Nested Vectored Interrupt Controller (NVIC). This is done with the following register write:

NVIC->ISER[0] = 1 << SysTick_IRQn; 

This sets the enable bit for the SysTick interrupt in the NVIC. If this enable bit is not set, the NVIC will ignore the SysTick interrupt even if it occurs. Make sure the correct ISER register and bit shift is used to enable the SysTick IRQ.

SysTick Timer Not Started

The SysTick timer peripheral must be configured and started to generate the interrupt events. This requires writing to the SysTick Control and Reload registers:

SysTick->LOAD = 48000000; // 1 sec period at 48 MHz  
SysTick->VAL = 0; // clear current value register
SysTick->CTRL = 5; // enable timer with interrupts

If the SysTick peripheral is not initialized correctly, it will not assert interrupts at the desired rate to trigger the LED toggle. Verify the timer reload, current value, and control registers are configured properly.

Priority Masking

Cortex-M0 supports priority grouping and masking to allow fine-grained control over interrupt preemption. This needs to be considered when multiple interrupts with different priorities are used.

// Set priority grouping format  
NVIC_SetPriorityGrouping(3);

// Set SysTick priority  
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(3, 2, 0));

If a higher priority interrupt occurs while the SysTick handler is running, it will pause SysTick interrupt handling. Make sure the SysTick priority is set appropriately compared to other active interrupts.

Fault Exceptions

On Cortex-M processors, faults and exceptions will take priority over handler mode interrupts. Unhandled faults like memory access violations, divide by zeros, etc can pause execution of the SysTick interrupt.

The HardFault_Handler can check the HFSR register to debug the cause of faults:

void HardFault_Handler(void) {
  volatile uint32_t hfsr = SCB->HFSR;
  // report and handle fault  
}

Proper error checking and handling needs to be set up to prevent/recover from faults for interrupt processing to continue.

Debug Halting

When debugging and single stepping through interrupt code, the debugger will often pause execution on the target processor. This halting of the core will stop timer interrupts from occurring until execution resumes.

Stepping through the interrupt handler slowly without resetting the timer peripherals can make it appear interrupts are not working. Allow the processor to run freely when validating interrupts.

Race Condition with Main Loop

Depending on the timing between the main program loop and the interrupt handler execution, a race condition may prevent the interrupt from toggling the LED.

For example, if the main loop turns the LED off right after the interrupt turns it on, the on state may not be visible. Introducing a short delay in the main loop can avoid this race condition.


while (1) {
  LED_Off(LED1);
  Delay_ms(5); // short delay 
}

Improper Simulation Model

The system simulation model may not match the actual MCU device functionality accurately. So interrupt behavior in simulation does not correspond to real silicon.

Using single step debugging on real hardware can help validate if the interrupt handler is being executed correctly before trying in simulation.

Conclusion

There are a variety of reasons why interrupts may not appear to work properly in Cortex-M0 simulations. Double checking the handler registration, interrupt enables, timer configurations, priority settings, fault handling, and race conditions can help troubleshoot the issue. Proper modeling and matching the simulation to actual MCU functionality is also important.

Identifying and fixing these common interrupt problems enables developers to take full advantage of the asynchronous processing capabilities of Cortex-M0 in their embedded applications.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article The diagram of register file in cortex-M0/M3
Next Article Cortex M0+ Image for MSP3
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

ARM Cortex-M vs Kirin A1

The ARM Cortex-M and Kirin A1 are two very different…

9 Min Read

Difference Between (Cortex-M3) STM32F1 Density Options for Boot from RAM

When selecting an STM32F1 microcontroller based on the Cortex-M3 core…

7 Min Read

Does ARM allow unaligned access?

The answer is yes, ARM does allow unaligned memory accesses,…

6 Min Read

What is the difference between UART and SPI?

UART (Universal Asynchronous Receiver/Transmitter) and SPI (Serial Peripheral Interface) are…

10 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account