Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Still locking after portEND_SWITCHING_ISR

Posted by Amon-Ra on March 13, 2012
Yesterday I asked a question about eternal lock after context switch (here https://sourceforge.net/projects/freertos/forums/forum/382005/topic/5111217)
But unfortunately, even right procedure of serving interrupt still causes eternal lock!

It looks like this:

static portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken=pdFALSE;
EXTI_ClearITPendingBit(EXTI_Line10);
irq++; //for debug purposes
if(irq==2)
__asm("NOP"); //here I can place a break, after that all tasks remain blocked forever
xSemaphoreGiveFromISR(IRQSemph, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);


There are two tasks, one for actual serving this interrupt, high-priority, which starts with xSemaphoreTake(IRQSemph, portMAX_DELAY);
and another, with lower priority, which is blocked, waiting signal form high-priority task.

I suppose, that when breakpoint is reached (irq count == 2), ISR interrupts this high priority task, while it is processing last ISR (irq == 1). But I don't understand, why this is causing this lock!

When I am entering xSemaphoreGiveFromISR, I can see that it's pxQueue->xTxLock is 0, so no actions with even list is taken, just data copy, inctement of xTxLock and return of FALSE;

Also pxQueue->xTasksWaitingToReceive->uxNumberOfItems = 2.

What does this mean, why there is two tasks, waiting for receive? The only one task, that uses this semaphore is my high-priority routine...

RE: Still locking after portEND_SWITCHING_ISR

Posted by Richard on March 13, 2012
I'm not sure I understand your problem, but could the issue be in your task implementation? Are you doing something like leaving the scheduler locked, or calling API functions with the scheduler locked?

Regards.

RE: Still locking after portEND_SWITCHING_ISR

Posted by Amon-Ra on March 13, 2012
No-no.
This is just a driver for radio tranciever.
Here is my high-priority task:

static void taskDriverIRQHandler(void *pvParameters)
{
u8 Status;
while(1)
{
xSemaphoreTake(IRQSemph, portMAX_DELAY);
xSemaphoreTake(SPI_DMA_Tx, portMAX_DELAY);
Status=ResetIRQ();
if(Status&TX_DS)
{
xSemaphoreGive(TxFIFOFree);
}
xSemaphoreGive(SPI_DMA_Tx);
}
}

I want it work in such way:
transmitter task (low priority) blocks on TxFIFOFree. Radio module asserts it's irq pin, causing external interrupt - it's isr is in my first post. ISR gives IRQSemph, also clearing EXIT bit.
taskDriverIRQHandler task unblocks, waits for all DMA transfers to be complete (actualy, they are all complete much earlier, I checked that), then sends to transiever SPI command to clear it's internal interrupt status - without that there will be no more interrupts, as EXTI handles high-to-low transition, and IRQ pin remains constant low.
Then taskDriverIRQHandler should give one more slot in TxFIFOFree, unblocking Tx task again.
But it doesn't work in that way!

What I know, is that Tx task finishes it's DMA transfers and blocks waiting TxFIFOFree. After some time, data is being sent by module and it asserts IRQ pin. ISR serves it, unblocks taskDriverIRQHandler, wich defenitly resets module's IRQ status.
Than some black magic happens, which I can not understand or even debug (because braking or even adding some tracing causes functions to execute slower and second interrupts does not ruin everything).
All I know is that second interrupt arrives, my system enters ISR, but tracing internals of xSemaphoreGive call, shows that IRQSemph is considered to be locked, it's pxQueue->xTxLock is 0, not queueUNLOCKED.
So, semaphore does not unblock it, just increment lock counter - but there is no other tasks running to unblock it either.


RE: Still locking after portEND_SWITCHING_ISR

Posted by Amon-Ra on March 13, 2012
I just found this damned bug.
Sorry for my questions, it is really stupid mistake.
Obviously, I shouldn't use NVIC-configuration routines like this:

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY-3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );

NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY-2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


I wanted to set priorities to
configLIBRARY_KERNEL_INTERRUPT_PRIORITY-3;
configLIBRARY_KERNEL_INTERRUPT_PRIORITY-2;
but I think i missed somethin in documentation on theese functions, so both priorities were set to 0! Highest possible priority, yeah.

When I checked it and replaced theese calls with conventional CMSIS

 NVIC_SetPriority(DMA1_Channel5_IRQn,configLIBRARY_KERNEL_INTERRUPT_PRIORITY-3);
NVIC_SetPriority(EXTI15_10_IRQn,configLIBRARY_KERNEL_INTERRUPT_PRIORITY-2);


all began to work.

Still really appreciate your help, big thanks!

RE: Still locking after portEND_SWITCHING_ISR

Posted by Amon-Ra on March 13, 2012
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);


This is the line I missed, btw)


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS