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.
stack overflow does not happen by enable vApplicationStackOverflowHook trace function
my code is simple enough and does not use queue ore semaphore
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 CPU_SR_Save() and CPU_SR_Restore() 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 ?
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 portDISABLE_INTERRUPTS() and portENABLE_INTERRUPTS() 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 CPU_SR_Save() disable interrupts?
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 CPU_SR_Save() 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.
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.
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
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. */
}
In which case, as you said before, the problem is occurring before you
attempt the actual context switch. Possibilities, either:
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
Something in your code has corrupted the data structures used by
FreeRTOS, or
The linker script is wrong, or
You are using heap_3 and the heap is overlapping other data, or
…something else that has caused the data structures to be corrupted.