Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


Stop a higher-priority ISR on an STM32F105

I have two external interrupt sources coming into an STM32F105 datasheet: http://www.kynix.com/uploadfiles/pdf65976/STM32F105R8T6.pdfQuestion. I want one of them (call it “IRQHigh”) to pre-empt the other (“IRQLow”). Currently, if IRQHigh is triggered during the IRQLow ISR, the program flow waits until I clear the IRQLow ITPending bit before it branches into the IRQHigh ISR.

The STM32F105 is a Cortex-M3Question-based microcontroller. It supports nested interrupts. My application is written in C, using GCC (arm-none-eabi-gcc) in Eclipse, with the STM32F1 Standard Peripheral Library.

Nxp M3
I think I have the priorities configured correctly but I must be missing something.

Here is the corresponding initialization code. I have stripped out AFB clock commands, GPIO config, etc, since each subsystem seems to work fine by itself:

  1. define IRQHIGH_EXTI_PORT GPIO_PortSourceGPIOA
  2. define IRQHIGH_EXTI_PIN GPIO_PinSource3
  3. define IRQHIGH_EXTI_LINE EXTI_Line3
  4. define IRQHIGH_EXTI_IRQn EXTI3_IRQn

  1. define IRQLOW_EXTI_PORT GPIO_PortSourceGPIOC
  2. define IRQLOW_EXTI_PIN GPIO_PinSource11
  3. define IRQLOW_EXTI_LINE EXTI_Line11
  4. define IRQLOW_EXTI_IRQn EXTI15_10_IRQn


NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;

// Sixteen levels of pre-emption priority, no subpriorities
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

// IRQHigh

// Connect EXTI Line to GPIO Pin
GPIO_EXTILineConfig(IRQHIGH_EXTI_PORT, IRQHIGH_EXTI_PIN);

// Configure EXTI line
EXTI_InitStructure.EXTI_Line = IRQHIGH_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

// Configure and enable EXTI Interrupt
NVIC_InitStructure.NVIC_IRQChannel = IRQHIGH_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// IRQLow

// Connect EXTI Line to GPIO Pin
GPIO_EXTILineConfig(IRQLOW_EXTI_PORT, IRQLOW_EXTI_PIN);

// Configure EXTI line
EXTI_InitStructure.EXTI_Line = IRQLOW_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

// Configure, but do not enable, EXTI Interrupt
NVIC_InitStructure.NVIC_IRQChannel = IRQLOW_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
The IRQ handlers are set up as so:

void EXTI3_IRQHandler(void)
{
IRQHigh();
EXTI_ClearITPendingBit(IRQHIGH_EXTI_LINE);
}

void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(IRQLOW_EXTI_LINE) == SET)
{
if (IRQLow()) // This returns a non-zero value if an overflow happened
{
CleanUpOverflow();
}

// Clear interrupt bit.
EXTI_ClearITPendingBit(IRQLOW_EXTI_LINE);
}
else // unknown EXTI source
{
ErrorHandler(ERR_UNKNOWN_EXTI15_10_IRQ); // This never happens
}
}
A few things of note:

IRQHigh() and IRQLow() each take significant time to complete (which is why I want one to interrupt the other)
IRQLow is not initially enabled, but is enabled down the line with NVIC_EnableIRQ(IRQLOW_EXTI_IRQn);
Within EXTI15_10_IRQHandler(), I’m getting a return value from IRQLow().
I have declared the xxx_IRQHandler() functions with and without attribute ((interrupt (“IRQ”))). I understand that this attribute isn’t necessary with Cortex-M3, but I tried anyway (and got the same results).
What am I doing wrong?

Update: With help from a comment by @Jeroen3, I’ve discovered that IRQLow is interrupting IRQHigh. Now I need to find out why...

Hi,

Too much code to understand what your problem is.

“Currently, if IRQHigh is triggered during the IRQLow ISR, the program flow waits until I clear the IRQLow ITPending bit before it branches into the IRQHigh ISR.”

I don’t think the priority is the right way round. IRQHigh should prempt immediately even when in IRQLow.

If you are using Freertos, do keep in mind that the priority (0>N, N>0) for ARM is “the other way around” that most people would expect.

PRIO 0 is HIGHER priority that PRIO 5 for ARM