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

Create standalone function to be loaded into Code memory

I have an application, for an 8051 device, that accepts commands, acts on them, and provides a reply.  I want to implement a command that will load code (for an new function) into a reserved section of Code memory so that the code will run when a different command jumps to it.  I'm having trouble getting the standalone function, which needs to access data arrays and other functions in the main application, to link (BL51 linker) without warnings.  My test function is:

void Cipher (unsigned char *in, unsigned char *out);

extern unsigned char xdata Data_Bffer[];
extern unsigned char xdata PlainTxt[];

void User1(void)
{
	PlainTxt[0] = 0x06;		//ASCII "ACK"
	PlainTxt[1] = 0xAA;
	PlainTxt[2] = 0x55;
	PlainTxt[3] = 0xAA;
	PlainTxt[4] = 0x55;
	PlainTxt[5] = 0xAA;
	PlainTxt[6] = 0x55;
	PlainTxt[7] = 0xAA;
	PlainTxt[8] = 0x55;
	PlainTxt[9] = 0xAA;
	PlainTxt[10] = 0x55;
	PlainTxt[11] = 0xAA;
	PlainTxt[12] = 0x55;
	PlainTxt[13] = 0xAA;
	PlainTxt[14] = 0x55;
	PlainTxt[15] = 0xAA;

	Cipher(&PlainTxt[0], &Data_Bffer[0]);
	return;
}

and the project also contains the following assembly code file:

$NOMOD51

PUBLIC   Data_Bffer
PUBLIC   PlainTxt
PUBLIC   Cipher

Data_Bffer   EQU   0DE0h
PlainTxt   EQU   0FF0h
Cipher	EQU	2104h

END

where the addresses for the data arrays and the function Cipher are taken from the .M51 file of the main application.  I'm getting warnings like the following from the linker:

*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  _CIPHER
    MODULE:  C:\Users\R\UserFunctions.obj (USERFUNCTIONS)

>>
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  ?_CIPHER?BYTE
    MODULE:  C:\Users\R\UserFunctions.obj (USERFUNCTIONS)

My Assembler, Compiler, and Linker command lines are unaltered from the defaults (in the Silicon Labs IDE); e.g. linker command line is:

RS(256) PL(68) PW(78)

If I change "Cipher" to "_Cipher" in the Assembly file, then the first warning goes away.  But I don't know what to do about "?_CIPHER?BYTE".  Anyone tried something like this before and know the fix?

Parents
  • OK, I understand your program structure now. Since data overlaying does not make sense for this function, I would use the linker direktive NOOVERLAY (or NOOL) and the linker warning about the root segment will go away.

    I think the assembler errors are obvious. You want to make the symbol ?_CIPHER ?BYTE public but you have not defined it. In the example below, I defined it, but you need to take the address of ?_Cipher?BYTE from your main program (like you do for _Cipher). The address is fixed when you link your main program. Depending on the memory model you use, this can be a data, pdata or xdata address.

    The same applies for the segment name, but I see no need to define the segment and make it public. Therefore I removed it.

    $NOMOD51
    
    PUBLIC   Data_Bffer
    PUBLIC   PlainTxt
    PUBLIC   _Cipher
    PUBLIC	 ?_Cipher?BYTE
    
    Data_Bffer     EQU  0DE0h
    PlainTxt       EQU  0FF0h
    _Cipher	       EQU  2104h
    ?_Cipher?BYTE  EQU  0030h  ; adapt this address!!!
    
    END
    

    Hint: If the function Cipher only gets pointers to xdata, you could redefine the function Cipher to take memory specific pointers. The prototype for this function would then be:

    void Cipher (unsigned char xdata *in, unsigned char xdata *out);
    

    This would be more efficient because both pointers would be passed in registers (in = R6/7 and out = R4/5) and you would not have to deal with ?_Cipher?BYTE. This change would require a modification of the function Cipher in your main program.

Reply
  • OK, I understand your program structure now. Since data overlaying does not make sense for this function, I would use the linker direktive NOOVERLAY (or NOOL) and the linker warning about the root segment will go away.

    I think the assembler errors are obvious. You want to make the symbol ?_CIPHER ?BYTE public but you have not defined it. In the example below, I defined it, but you need to take the address of ?_Cipher?BYTE from your main program (like you do for _Cipher). The address is fixed when you link your main program. Depending on the memory model you use, this can be a data, pdata or xdata address.

    The same applies for the segment name, but I see no need to define the segment and make it public. Therefore I removed it.

    $NOMOD51
    
    PUBLIC   Data_Bffer
    PUBLIC   PlainTxt
    PUBLIC   _Cipher
    PUBLIC	 ?_Cipher?BYTE
    
    Data_Bffer     EQU  0DE0h
    PlainTxt       EQU  0FF0h
    _Cipher	       EQU  2104h
    ?_Cipher?BYTE  EQU  0030h  ; adapt this address!!!
    
    END
    

    Hint: If the function Cipher only gets pointers to xdata, you could redefine the function Cipher to take memory specific pointers. The prototype for this function would then be:

    void Cipher (unsigned char xdata *in, unsigned char xdata *out);
    

    This would be more efficient because both pointers would be passed in registers (in = R6/7 and out = R4/5) and you would not have to deal with ?_Cipher?BYTE. This change would require a modification of the function Cipher in your main program.

Children
  • Sorry, I did not understand what you meant by "define" - from your correction of my example code I now see what you meant.  Unfortunately, ?_Cipher?BYTE does not appear in the .M51 file from my main program so I can not get the address - this is why I did not have it on a line with an EQU.  Both "in" and "out" appear in the .M51 file, perhaps I could use them instead?

    I'm going to try your suggestion of redefining the prototype for Cipher to specify xdata, that sounds like a straight forward fix, and I don't see any reason not to (this was a function I obtained from somewhere else, and had left the way it was).  And I will use the NOOVERLAY directive.

  • Changing the Cipher prototype to specify XDATA for the arguments and then using the NOOVERLAY directive eliminated the warnings I was receiving.  Thanks.