I'm using the Silicon Laboratories C8051F345 with the Keil IDE.
I now have two different projects of which the firmware won't execute. If I comment random pieces of code the firmware will execute. I am still within the memory limits of the device.
From my point of view, the compiler is not configured correctly for the device or I assign my variables incorrectly. I ran out of ideas, tired of searching and pulled almost all my hair out of my head.
I program alone and don't have anyone to look at my source.
I want to ask if someone experienced will please have a look at my project to point any possible mistakes or problems.
I would like an example of something that does not "absolutely need to be done immediately after reset is gone" where it will be advantageous to locate it in startup.a51. Sure, with the ultimate care, you can run your entire program from Satartup.a51 but I just can not imagine anything beyond what I posted where it will be advantageous to do so.
Erik
"I would like an example of something that does not 'absolutely need to be done immediately after reset is gone'..."
I think it'd be better if any examples and/or further discussion of this particular point were taken to a separate thread...
Sorry, but I don't have the time follow this on for too long but will say this:
I have occasionally had to support code with unusual memory maps and awkward battery backed non-volatile rollback data recovery.
Sometimes these could be placed outside startup.a51 and sometimes, due to timing constraints, to do so would have caused a window for potential data loss.
The word advantageous could simply refer to better code layout/structure/modularity.
My point really was that a well seasoned developer should not be afraid of writing or modifying any mixed C/ASM code - So long as that developer has sufficient understanding of the whole environment.
And that includes the startup code.
Whoops - Just seen Andy's response after I posted a response.
I will refrain from continuing the discussion here.
I do not call any functions from the startup. It is the standard startup code that jumps to my C source, like it should. But it does not go to main() at all. This is what it looks like:
This is the last assembly executed in the startup file.
C:0x10ED 758107 MOV SP(0x81),#0x07 196: LJMP ?C_START C:0x10F0 02112E LJMP C:112E
So the C source at 0x112E looks like this. But 0x112E is not at the entry of u8 Chech_RX_Message(...), it is at the last closing brace of this function. So the startup code will jump to the last closing brace (0x112E) of this function.
u8 Check_RX_Message(TCommsBuffer *RXBuffer) { u8 LocalLoop; u8 Checksum = CLEAR; u8 State = CRC_ERROR; // Calculate the header checksum for (LocalLoop = 0; LocalLoop < 4; LocalLoop ++) { Checksum ^= ((u8*)(&RXBuffer->Protocol.StartByte))[LocalLoop]; } // If the header checksum is correct if (Checksum == RXBuffer->Protocol.HCS) { // If there is protocol data if (RXBuffer->Protocol.Length) { Checksum = CLEAR; // Calculate the protocol data checksum for (LocalLoop = 0; LocalLoop < RXBuffer->Protocol.Length; LocalLoop ++) { Checksum ^= RXBuffer->Protocol.Data[LocalLoop]; } // If the data checksum is correct if(Checksum == RXBuffer->Protocol.Data[LocalLoop]) { // Set the state value State = RXBuffer->Protocol.Command; } } else { // Set the state value State = RXBuffer->Protocol.Command; } } // Return the state return (State); }--->0x112E
Then the software will reset and it will continue with the same process over and over.
the SILabs deviates (f3x-up) have the watchdog running after reset. You need to disable it in startup.a51
then, when you get to code that actually feed the dog, you can enable it again.
PS the sensible SILabs derivatives (f0x-f2x) do not have the WD running after reset.
PPS in various fora there has been umpteen posts on this subject it must be a REAL gotcha!
No I didn't kill the dog in the startup code but its dead in the beginning of the main() function. I can kill it in the startup code but I doubt this has anything to do with the dog. The way the code behaves (jumping to the incorrect address).
It seems more like a compilation error. Jumping to the last closing brace of a function that should not be executed after startup???
I have read umpteen posts - all with different symptoms - that were solved by killing the dog in startup. The 'secret code' that executes between startup and main seems to be the culprit.
Do yourself a favor and kill the dog right here
STARTUP1: ;; disable watchdog (should be enabled after initialization) mov xxxx ; Disable WDT
If that is not it (I'll bet you dollars to doughnuts it is) you have spent two minutes on eliminating one possible cause.
By the way, this is not a PC so you MUST have void main (void)
{ .... while(1) {
..... }
}
OK! I apologize erik. I killed the dog in the startup and the firmware executed!!! Do I owe you dollars or donuts?
Anyway, let me not get too excited yet. Let me first test that everything is working fine and I'll let you guys know.
Don't get so upset about the main(). It is implemented as you show, I just "abbreviated".
Funny how the dog can cause such funny symptoms?
Do I owe you dollars or donuts? as I bet you dollars to doughnuts, you could owe me a doughnut Krispy Kreme, please :) But since you did not accept the bet you are home free.
Funny how the dog can cause such funny symptoms? not really, the dog is asynchronous to the code, and thus can hit any possible way. There has been posts such as "when I remove one variable, it starts working'
Glad we got you going
But it all makes sense now. If I am correct, that explains the reason when I add more code (more variables) it will stop working.
During startup all these variables need to be initialized and the more variables to initialize the more time it takes. And if I don't look after the puppy during this time it will cause a reset. So just kill the puppy!
So just kill the puppy! ... when you get going (if it is anything critical) resussicate the puppy at the start of main()