Now I’m debugging my port on my 4-core RISC-V Soc and encountering some problems. I have been working on it for days but I have no idea how to solve it. I need some help.
I create one task for each cpu. They are thread_0
~ thread_3
, binding core 0
~ core 3
. All of them have the priority 32
, which is the highest in the system. they take the Mutex, print and then delay.
void task_entry(void *parameter)
{
while (1)
{
int id = csi_get_cpu_id();
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{
printf("[%s] in %lu core, count: %d\r\n", pcTaskGetName(NULL), (unsigned long)id, g_count++);
xSemaphoreGive(xMutex);
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
Preemption is enabled.
When configRUN_MULTIPLE_PRIORITIES
is set to 0
. Sometimes it is stuck after running for some seconds, and the debugger shows that all the cores are running IDLE tasks, even there’s a higher priority user task in pxReadyTaskLists[32]
.
(gdb) i th
Id Target Id Frame
1 Thread 1.1 (CPU#0 [running]) prvIdleTask (pvParameters=<optimized out>)
at /home/phf/yoc212/components/freertos/FreeRTOS/Source/tasks.c:5847
2 Thread 1.2 (CPU#1 [running]) prvPassiveIdleTask (pvParameters=<optimized out>)
at /home/phf/yoc212/components/freertos/FreeRTOS/Source/tasks.c:5725
3 Thread 1.3 (CPU#2 [running]) prvPassiveIdleTask (pvParameters=<optimized out>)
at /home/phf/yoc212/components/freertos/FreeRTOS/Source/tasks.c:5725
* 4 Thread 1.4 (CPU#3 [running]) prvPassiveIdleTask (pvParameters=<optimized out>)
at /home/phf/yoc212/components/freertos/FreeRTOS/Source/tasks.c:5725
But now thread_3
with priority 32
is in pxReadyTasksLists[32]
, which is not scheduled.
(gdb) p (TCB_t)*((TCB_t*)pxReadyTasksLists[32]->xListEnd->pxNext->pvOwner)
$2 = {pxTopOfStack = 0x500b5f70, uxCoreAffinityMask = 8, xStateListItem = {xItemValue = 0,
pxNext = 0x5002c088 <pxReadyTasksLists+1296>, pxPrevious = 0x5002c088 <pxReadyTasksLists+1296>,
pvOwner = 0x500b6450, pvContainer = 0x5002c078 <pxReadyTasksLists+1280>}, xEventListItem = {xItemValue = 30,
pxNext = 0x5009fa88, pxPrevious = 0x5009fa88, pvOwner = 0x500b6450, pvContainer = 0x0}, uxPriority = 32,
pxStack = 0x500b0ac0, xTaskRunState = -1, uxTaskAttributes = 0,
pcTaskName = "thread_3", '\000' <repeats 23 times>, uxTCBNumber = 11, uxTaskNumber = 0, uxBasePriority = 32,
uxMutexesHeld = 0, pxTaskTag = 0x0, pvThreadLocalStoragePointers = {0x0, 0x0, 0x0, 0x0, 0x0},
ulRunTimeCounter = 0, ulNotifiedValue = {0}, ucNotifyState = "", ucStaticallyAllocated = 0 '\000'}
I printed some logs to the memory and dump it from GDB. And I found the problem.
There was a previous call prvYieldCore( 3 )
and the IDLE
task in core-3
is set to -2
, namely taskTASK_SCHEDULED_TO_YIELD
. I think this may stops prvYieldForTask
from selecting core-3
to yield for the thread_3
. So this task doesn’t run thus the other cores can only run IDLEs when configRUN_MULTIPLE_PRIORITIES
is set to zero.
Because only the condition if( ( taskTASK_IS_RUNNING( pxCurrentTCBs[ xCoreID ] ) != pdFALSE ) && ( xYieldPendings[ xCoreID ] == pdFALSE ) )
is satisfied that core-3
can be selected as xLowestPriorityCore
in prvYieldForTask.
So core-3
cannot enter software-interrupt
to call vTaskSwitchContext()
any more because no one triggers it, after pxCurrentTCBs[3]->xTaskRunState
is set to -2
.
Should an IPI be sent to core-3
at a specific time to solve this problem? When and where to send it?
I wrote a simple log function in mylog.c
and mylog.h
log the events. tasks.c and FreeRTOS.h are also modified, to add some tracepoints.
The codes and logs are here.
Thank you for your time!
files-and-logs.7z (64.4 KB)