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

IAP checksum read

Hi,

I'm using the P89LPC932A1 and attempting to read the global checksum using IAP during normal program execution. I have used this knowledgebase article as my guide:

http://www.keil.com/support/docs/2554.htm

So basically, I added this function to my code:

long unsigned IAP_ReadGlobalCRC (void)  {
  ACC = 6;                                          // MOV  A,#06H
  return ((unsigned char (code *)(void)) 0xFF03)(); // LJMP 0FF03H
}

As you can see, I changed the IAP vector from FF00 to FF03, which is what it should be. When I run the code on a real part, I do not get what I expect to get back. I generally receive back something like 0x0000000056. This is not the correct global checksum. Am I missing something? Thanks, Phil

  •   return ((unsigned char (code *)(void)) 0xFF03)(); // LJMP 0FF03H
    Is this actually guaranteed to compile to an LJMP? Could it not give an LCALL - unless common tail merge optimisation is enabled?

  • Thank you for replying to my thread. I think I might be "seeing the light". Below, I have posted what this compiles to.

    Basically it seems that after LCALL FF03, the 32-bit result should be in R4-R7 with the MSB being in R4. But this code looks like it overwrites R4-R6 with 00's and then leaves R7 as is. This would explain why I get 0x000000XX as the return value.

    However, I'm a bit confused by this c code to begin with. First, why would Keil say that this is the way to do it when the compiler generates code that overwrites the true result. How *should* this be done using c?

    Much Thanks
    Philip

    This is what it compiles to in my project:

                 ; FUNCTION IAP_ReadGlobalCRC (BEGIN)
                                               ; SOURCE LINE # 80
                                               ; SOURCE LINE # 81
                                               ; SOURCE LINE # 82
    0000 7406              MOV     A,#06H
                                               ; SOURCE LINE # 84
    0002 12FF03            LCALL   0FF03H
    0005 E4                CLR     A
    0006 FC                MOV     R4,A
    0007 FD                MOV     R5,A
    0008 FE                MOV     R6,A
                                               ; SOURCE LINE # 85
    0009         ?C0007:
    0009 22                RET
                 ; FUNCTION IAP_ReadGlobalCRC (END)
    

  • Ouch. Didn't spot this. I think this knowledgebase article has a typo:

    long unsigned IAP_ReadGlobalCRC (void)
    
    should be
    
    unsigned long IAP_ReadGlobalCRC (void)
    

    After chaning, the code looks like it compiles correctly to:

                 ; FUNCTION IAP_ReadGlobalCRC (BEGIN)
                                               ; SOURCE LINE # 80
                                               ; SOURCE LINE # 81
                                               ; SOURCE LINE # 82
    0000 7406              MOV     A,#06H
                                               ; SOURCE LINE # 83
    0002 12FF03            LCALL   0FF03H
                                               ; SOURCE LINE # 84
    0005         ?C0007:
    0005 22                RET
                 ; FUNCTION IAP_ReadGlobalCRC (END)