Hi guys, I'm trying to use the Wait mode (that turns off the CPU clock of the Coldfire V1) to implement low power idle task in a RTOS.
This RTOS was developed for me and me colleagues, in order to have an very lightweight OS to use with sensor networks.
The problem occur when the OS calls the Idle task. This task puts the MCU in stand by to reduce the comsumed power when there are no task eligible to run. Any peripherals can wakeup the CPU, exiting from the idle task.
IdleTask(void)
{
_Wait;
}
If the system suffer with high load (a lot of interrupts - communication in serial line, wireless line, timer interrupts, etc), the CPU sometimes gets inconsistent generating any kind of error (memory access error, illegal opcode error, disabled interrupts, etc. If we turn off the wait instruction, these error don't occur and it's work fine.
What could be the reason of this issue ???
I appreciate any help.
Thanks in advance,
Gustavo
解決済! 解決策の投稿を見る。
Problem solved.
I turned off the "Flash speculation module" and now everything is working.
No more problems with reset due to access errors.
I concluded that the flash speculation module is generating wrong address when using the wait mode and lots of interrupts.
I would check your stack, and make sure that it is being restored properly when the system wakes up from the wait.
---Tom
Hi Tom. Thank you for your help.
How can i send you the code to analysis?
However, i have some doubt. How can be possible the stack be correct in all the fases of the code and just be incorrect in the local of the wait instruction? Thus, it works, but if there are a lot of interrupts, the errors occur.
PS: a simple version of the code, without the applications tasks are available at:
http://code.google.com/p/brtos
Any time a system craters under stress it is usually because the stack space is too small. However, if it is just adding that one function that is causing trouble, it might be another condition. See this forum thread. While it's talking about a HCS08 derivative, I think the issue might be similar to what you are having.
Or, maybe it is just calling a function to execute the one wait instruction that bothers me for some reason...
---Tom
Hi Tom,
I do not think that my problem is the same from the other thread, cause i disabled the nesting interrupt of the system, just to save stack.
You can see that in this code:
/* Initialization of CPU registers */
asm {
/* CPUCR: ARD=0,IRD=0,IAE=0,IME=1,BWD=0,FSD=0 */
move #0x10000000, d0
movec d0,CPUCR
}
I don't know what to do. Thus, i can't understand your last sentence.
Use that link to read to the forum thread again. How did he really solve the problem, even though nested interrupts were discussed? He revised the task scheduler, by yanking that STOP instruction out of an interrupt handler.
OK, so calling a function to do a WAIT is not the same thing as an interrrupt handler. However, think about it. The system is idle, so the scheduler calls the function. The function is entered, and the context of the task scheduler is placed onto the stack. Now you WAIT. When an interrupt brings you out of the wait state, the function exits, and the context of the task scheduler is restored. That works fine as long as you can guarantee that the next interrupt is not going to occur until after the function exits. If you happen to get two interrupts in a row, where will the program be?
1) The function exit code is unreeling the stack to restore the task scheduler context, and now the interrupt handler butts in. The stack might get pranged.
2) Or, the function has not exited, and the interrupt uses the context of... what? The function? Your handlers might be relying on some portion of the task scheduler's context to do things (access buffers?) and it simply is not there.
Short answer is: take the WAIT out the function call.
---Tom
Problem solved.
I turned off the "Flash speculation module" and now everything is working.
No more problems with reset due to access errors.
I concluded that the flash speculation module is generating wrong address when using the wait mode and lots of interrupts.
Hi Tomm,
I'm back. I did a lot of tests and could not conclude anything. However, analyzing the stack i notice the following behavior:
1) The idle task executes a STOP instruction (Wait mode);
2) The Serial RX interrupt wakes the processor;
3) Before any instruction of the Serial RX handler executes, occurs an Access Error;
4) You can see in the stack that the PC return point is wrong. The Serial RX handler is located in the position 0x3540 (as you can see in the other figure). However, the return point saved by the access error interrupt is 0xFC3540. Why this "FC". The hardware handles the Exception Stack Frame Definition + PC saving in the interrupt. This "FC" seems to be the cause of the access error.
What is your opinion about this error? Again,this just happens when i uses the stop instruction.
PS.: Notice that i'm using the Interrupt mask enable. This option of the CPUCR register forces the processor to raise the interrupt level mask (SR[I]) to 7 during every interrupt exception. This capability is provided to assist when porting S08 application code to ColdFire. This is the reason to that 2700 in the Exception Stack Frame of the Access Error exception.
Ok Tom, thank for you help.
I'm traveling now ... going to Houston/TX.
As soon as i return to Brazil i will try your tip.
Just informing:
I'm using an External Crystal of 4 Mhz and Engaged FLL mode (FEE) / High gain. Bus frequency of 24Mh.