I have written some code for a Silabs C8051F330 CPU, compiled it and then obviously some C51STARTUP code is generated that initialize the variables. Using my USB debug adaptor I discover the execution got stuck in the C51STARTUP code and it never exits it to the main program. What could be a possible cause for this and how can I fix it?
I will do that, only problem is I need to jump into the assembler code and figure out what it is doing and which variable it is trying to do what with. The asm code is a JC instruction back to the some place down from the start of the C51STARTUP code. In it a bit difficult to determine the actual operation from the assembler if you don't know what it is trying to do. I will give it a go!
The Watchdog Timer of the 330 is enabled on reset. So is most likely that your startup code takes too long -> the watchdogs times out, resets the 330 and you'll never reach the main function.
So add a copy of the startup code to your project and disable the watchdog as early as possible.
Or modify the startup code to ensure that it keeps the watchdog from timing out...
What do you mean with "Or"? He does not reach the main function, so this is the only place I can think of. Am I missing something?
I don't know if it is the watchdog timing out. I use the USB Debug adapter and I can see it tries to initialize some variables using strange Assembler code. The variables are simple unsigned integers and bits, no arrays. Thus it should be quick. I can see, single stepping, where it loops back to about 10 instructions after the C_STARTUP code and doing the same thing over and over again. I going to remove the variable initialization part and will do that in the main program en see what happen. This can only happen tomorrow.
I mean he could either just disable the watchdog or make the startup code "kick" the watchdog at appropriate points so that it doesn't time out.
(Both of which, of course, assume that the problem is actually due to the watchdog)
Doesn't the standard startup code include zeroing all of XDATA...?
I mean he could either just disable the watchdog or make the startup code "kick" the watchdog at appropriate points so that it doesn't time out. kicking is not advised, there are, in some cases, more time spent between startup and main than in startup.
besides the OP refer to 'strange assembler code', the code in startup is as simple as can be.
we are back a the old point "to do embedded you need, at least, some assembler.
Erik
To understand what is happening during start up you need to look at the the file <STARTUP.A51> supplied with the compiler and added during link time. From this file it can be seen that all memory variables are setup and initialized. Looking at this assembler code, if big xdata arrays and constants are setup it will take a while to do so. Only four bytes in external memory were set to a value, but even after removing them it still did not work. What I have done is not to initialize any variable in the definition of it but rather later, just before running the main program. This then also allow me to control what must happen and the possibility of a watchdog reset is eliminated, because the watchdog will be stopped before that. This seems to work well, but I still don't know why the startup code got stuck!
After removing all variable initialization from the start up code, all the start up code is doing now is to fill the internal memory from 7fh to 0h with 0, setup the stack pointer and get out. This works well!
Paste your startup code.
You can modify your startup code to initialize (or de-initialize) any peripheral if you want.
What I have done is not to initialize any variable in the definition of it but rather later, just before running the main program. That cannot make much of a difference. XDATA variables are always of static storage duration, and such variables are always initialized to something, regardless of whether there's an initializer in the definition or not. If you don't supply one, the initializer is zero by default.
So you've only switched those variables from being, effectively, initialized via a big memcpy() from ROM to RAM, to a big memset(). That's at most a factor of two faster itself, and at lesst 50% slower in total, once your manual post-initialization has been done.
To really have an effect, you would have to disable the intialization mechanism centrally in the runtime environment. And the place for doing that is not in STARTUP.A51, but rather INIT.A51