halt in the loop in vListInsert

I were working on porting FreeRTOSv8.2.3 to our CK610 cpu core.. the first task can work now . but it can’t switch task. I trace it and find it halt in the loop in vListInsert function. According to those comment , I check my code and exclude some. 1. stack overflow does not happen by enable vApplicationStackOverflowHook trace function 3. my code is simple enough and does not use queue ore semaphore 4. my code is simple enough and does not use queue ore semaphore But for case 2, I am not sure my design is okay or not . I doesn’t set interrupt priority for my interrupt instead of disable and enable global interrupt I disable/enable global interrupt by CPUSRSave() and CPUSRRestore() functions.. there are only timer and system software trap interrupt source.. my view seems to be good.. but it really halt in the loop .. Could you help to explain ? ~~~

define portDISABLE_INTERRUPTS() ulPortSetIPL( 1 )

define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )

portLONG ulPortSetIPL( portLONG x) { static portLONG cpu_sr = 0x80000100;
if (x)
{
    cpu_sr = CPU_SR_Save();
}
else
{
    CPU_SR_Restore(cpu_sr);
}

return cpu_sr;
} ~~~

halt in the loop in vListInsert

I think this needs to be taken one step at a time, particularly as I can’t download the datasheet for the CK610. The first thing to check is that the task is really starting the way you expect it to be. When you created the initial stack for the task did you give each register a known value, then check that the correct values were in the correct registers when the task started running? As for the portDISABLEINTERRUPTS() and portENABLEINTERRUPTS() macros – those should do nothing more then disable and enable interrupts respectively, however you want to do that (globally or just masking a sub-set of priorities). In your function, if x is non-zero, I assume it is supposed to disable interrupts – does calling CPUSRSave() disable interrupts?

halt in the loop in vListInsert

The first thing to check is that the task is really starting the way you expect it to be. When you created the initial stack for the task did you give each register a known value, then check that the correct values were in the correct registers when the task started running?
yes, I did, I dump PC and PSR register which is in initial stack …it is right .. if x is non-zero, I assume it is supposed to disable interrupts – does calling CPUSRSave() disable interrupts? yes,, if x is 1, disable global interrupt to mask all interrupt.. if x is 0, enable global interrupt and clear all interrupt.

halt in the loop in vListInsert

I think with the amount of information available, and without seeing a lot of your code, and being able to step through the code on the hardware, it is going to be very difficult to make useful suggestions. I think from your original post you say the first task is starting, but then the first time a context switch is attempted it gets stuck in the loop. Is the context switch coming from an interrupt, or is the task trying to perform a context switch itself by yielding or calling a blocking API function? I would recommend starting with the tick interrupt OFF, so getting the task level context switch working first. How is the task context switch performed? A software interrupt? Put a break point in the interrupt and step through it as the assembly level so you can see exactly what it is doing – somewhere it is corrupting memory which is why you are ending up in the loop.

halt in the loop in vListInsert

the interrupt controller is comprosed of IRQINTEN, IRQINTMASK, IRQINTCLR, and IRQINTSTS to support 32 interrupt…

halt in the loop in vListInsert

to start first task, I use the following code without task switch OSIntCtxSw: lrw r4, pxCurrentTCB ld.w r4, (r4) // the current task stack pointer is the first member ld.w sp, (r4)
ld.w r1, (sp,0)                 // Get the PC for the task
mtcr    r1, EPC

ld.w r1, (sp,4)                 // Get the PSR for the task
mtcr    r1, EPSR

addi    sp, 8                   // Increment SP past the PC and PSR

ldm r1-r15,(sp)                 // Load R0-R13 from the stack
addi    sp, 32                  // Increment SP past the registers
addi    sp, 28                  // Increment SP past the registers

rte                         // Return to new task

then the first task run and enter vTaskDelay funciton. then halti in the loop at last 

halt in the loop in vListInsert

the real code use soft trap to do context switch, but it has not run it… I just send all porting file to you by mail

halt in the loop in vListInsert

the question real status is the first task run after call OSIntCtxSw, then halt in loop after call vtaskdelay, no context switch happen !!!

halt in the loop in vListInsert

Have you stepped through the code in the debugger, from the vTaskDelay() function onwards, to see how it gets into the loop?

halt in the loop in vListInsert

yes.. i did. after enter vtaskdelay, it call prvAddCurrentTaskToDelayedList, then call vListInsert, then get stuck in the following loop code, for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ { /* There is nothing to do here, just iterating to the wanted insertion position. */ }

halt in the loop in vListInsert

In which case, as you said before, the problem is occurring before you attempt the actual context switch. Possibilities, either: 1) The C start up code has not correctly initialised the variables used by FreeRTOS so the data structures were already corrupt before the scheduler started, or 2) Something in your code has corrupted the data structures used by FreeRTOS, or 3) The linker script is wrong, or 4) You are using heap_3 and the heap is overlapping other data, or 5) …something else that has caused the data structures to be corrupted.

halt in the loop in vListInsert

The BaseStack prototype should be unsigned long instead of long, now it works well 🙂