Hello!
There happens deal lock in prvTimerTask() during porting arm ca7( Reference ca9 ). I have just started with freertos smp so confused with the critical section.
The backtrace when dead lock occurs is as follows:
Thread 1 (Thread 1.1):
#0 0x80401588 in spin_lock (lock=0x80420240 <task_lock>) at ./drivers/spinlock.h:18
#1 0x80401934 in xPortSpinLockTask () at ../../Source/portable/GCC/ARM_CA7/port.c:344
#2 0x804045f4 in vTaskSuspendAll () at ../../Source/tasks.c:2929
#3 0x80408b78 in xQueueSemaphoreTake (xQueue=0x80421a50 <ucHeap+120>, xTicksToWait=4294967295) at ../../Source/queue.c:1585
#4 0x80401f58 in prvEventSemaphoreTask (pvParameters=0x0) at main.c:254
#5 0x00000000 in ?? ()
Thread 2 (Thread 1.2):
#0 0x80401588 in spin_lock (lock=0x80420240 <task_lock>) at ./drivers/spinlock.h:18
#1 0x80401934 in xPortSpinLockTask () at ../../Source/portable/GCC/ARM_CA7/port.c:344
#2 0x804066e8 in vTaskEnterCritical () at ../../Source/tasks.c:5349
#3 0x80409b14 in vQueueWaitForMessageRestricted (xQueue=0x80421984 <xStaticTimerQueue.0>, xTicksToWait=0, xWaitIndefinitely=1) at ../../Source/queue.c:2842
#4 0x8040b410 in prvProcessTimerOrBlockTask (xNextExpireTime=0, xListWasEmpty=1) at ../../Source/timers.c:663
#5 0x8040b34c in prvTimerTask (pvParameters=0x0) at ../../Source/timers.c:617
#6 0x00000000 in ?? ()
I check the calling flow and fine comments in vQueueWaitForMessageRestricted()
but even it should be called with the scheduler locked and not from a critical section.
prvLockQueue( pxQueue ) was called which will enter critical section and try get both lock, but task lock has been acquired. I’m wondering what I did wrong during porting.
My spinlcok implements as follow:
spinlock_t task_lock;
spinlock_t isr_lock;
typedef struct spinlock {
volatile uint32_t lock;
} spinlock_t;
static inline void spin_lock(spinlock_t *lock)
{
unsigned long tmp;
__asm__ __volatile__(
"1: ldrex %0, [%1]\n"
" cmp %0, #0\n"
" wfene\n"
" strexeq %0, %2, [%1]\n"
" cmpeq %0, #0\n"
" bne 1b\n"
" dmb"
: "=&r" (tmp)
: "r" (&lock->lock), "r" (0x1)
: "cc");
}
static inline void spin_unlock(spinlock_t *lock)
{
__asm__ __volatile__(
"dmb ish\n"
"str %1, [%0]\n"
"dsb ishst\n"
"sev"
:
: "r" (&lock->lock), "r" (0x0)
: "cc");
}
Looking forward to your reply.