Experts, I have a 'C' program that contains an array of around 10 unsigned int's. If I initialise it during the declaration, the code never enters main() (I placed a breakpoint on the first instruction inside my main() but it never got hit). unsigned int array[10]={0,0,0,0,0,0,0,0,0,0}; // does not work.
If I remove the initialisation part, it works. Why? MCU = C8051F340 (Silabs) Keil version = C51 COMPILER V7.10 Assembler command line flags: XR GEN DB EP NOMOD51 Compiler command line flags: PW(80) SB LC OT(9,Size) CD DB OE DF(__F340_VER__) Large Linker command line flags: RS(256) PL(68) PW(78) IX
Thanks.
Regards, Ganesh
Running out of stack space?
But a more probable cause: You have a watchdog that is running and not getting kicked in time because the decompress/copy code in the startup file takes too long.
Mr. Westermark, Thank you for taking time to answer.
a) Running out of stack space: I am not too sure if I understand this comment. Are initialised globals placed in stack space?
b) Watchdog: This could possibly be a cause because if I reduce the no. of global variables that I initialise, everything works fine. But then how should I handle this case? Isn't a watch dog timer disabled by default on power up? If not, where should I disable it (obviously it cannot be in my main() because that would execute well after the variables are initialised).
Regards, Ganesh Okade
If the problem is with the watchdog, then you will have to update the assembler startup file.
Have you checked what the datasheet says about the watchdog?
Have you looked at the startup file?
There is no such thing as "stack space".
The 8051 uses the DATA/IDATA space for the stack - if there's not enough of that left to meet your stack requirements, then There Will Be Trouble Ahead...
Of course there are such a thing as "stack space". But that does not imply that the processor has hard-coded stack bytes but represents the memory region(s) the application require to handle worst-case nesting/state saves.
Most processor architectures requires a RAM address range to be shared between stack and variables, and will get into trouble depending on the amount of variables that gets allocated into this RAM address range or if the MMU configuration (large processors) hasn't reserved a large enough address space for the stack.
In some situations, a program may look like it is working even when variables are stored overlapping with the minimum required stack space.
As long as the variables are not read, the program may not notice that they have been corrupted by some stack operation. And as long as they are not written, they will not corrupt the stack.
"But that does not imply that the processor has hard-coded stack bytes"
Sorry - that's what I meant.
The 8051 doesn't have a dedicated "STACK" space in the same way that it has DATA space and CODE space and XDATA space, etc...
"In some situations, a program may look like it is working even when variables are stored overlapping with the minimum required stack space."
For an analogy, think of building sandcastles on the beach: if you have all your fun between tides, you will be fine; if the tide comes in while you're still trying to build your sandcastle, you will be in trouble...
Gentlemen: Thank you again for your responses.
As suspected by Mr. Westermark, the problem indeed was that the watchdog was causing a reset. I looked at the MCU manual and found that the watchdog on this chip is enabled on reset. I moved the code to disable the watchdog from main() to startup.a51 and now every thing works fine!
I really appreciate your time taken to help me out.
Hello Ganesh,
Even I faced the same(watch dog causing reset) problem while working for FSM using silabs controller and SDCC compiler. Controller was getting reset continuously.
After many trials I finally disabled the watchdog in the compiler startup.c and the result is positive.
But turning off the watchdog is normally not something you want to do. In real life, the watchdog is something you should be ready to pay extra for, because you really do want your hardware to be restarted in case something goes wrong.
Your code may be ok, but if they mount your hardware besides a huge contactor to turn on the lights for a sports stadium, your hardware can go into a spin when the contactor gets activated. It isn't always so easy to test that the electronics can handle big peaks on the supply or signal wires or can survive strong EMI, unless you have very special test equipment or sends it to a laboratory for testing. The watchdog is there as a final resource to _maybe_ solve the problem if something goes wrong. I write _maybe_ because a watchdog can't solve a latchup problem. For a latchup, the affected chip must be without power for a significant amount of time - it can take days without power for the latchup to release.
startup.c no such thing it is startup.a51
But turning off the watchdog is normally not something you want to do. In real life, the watchdog is something you should be ready to pay extra for, because you really do want your hardware to be restarted in case something goes wrong. there is a caveat: the Keil 'preprocessing' do not kick the puppy and thus with these chips you need to muzzle the puppy in startup.a51 and release it at the top of main
Erik
It is always problematic to have a watchdog that runs too fast. For most applications it will be ok to have a watchdog timeout of 1-10 seconds. For a processor that can't decompress all variables within one watchdog cycle, Keil really should consider releasing a version of the library that kicks the watchdog during the startup operations. A watchdog works best if it can be turned on as soon as possible - best is that it is turned on by a fuse, so it is turned on before the first instruction is processed.
Keil really should consider releasing a version of the library that kicks the watchdog during the startup operations. that would require, lots and lots of versions. A watchdog works best if it can be turned on as soon as possible - best is that it is turned on by a fuse, so it is turned on before the first instruction is processed. I do not have a problem with a WD that can be turned off, if turning it off is complex enough to make the likelyhood of runaway doing so is less then 1/1000000
"that would require, lots and lots of versions." Not at all. All they need is for the RTL to call a helper function for kicking, and expecting you to supply such a function.
there is a caveat: the Keil 'preprocessing' do not kick the puppy and thus with these chips you need to muzzle the puppy in startup.a51 and release it at the top of main
Try reading the instructions in init.a51 instead.
"I faced the same (watch dog causing reset) problem"
That is not a problem - that is the intended behaviour of a watchdog!
If your code is leaving it too long before "kicking" the watchdog, then the problem lies in the code - not the watchdog!