This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Firmware does not execute

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.

Parents
  • 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.

Reply
  • 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.

Children
  • 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.

    Erik

    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)
    {

    .....
    }

    }

    Erik

  • 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

    Erik

  • 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()

    Erik