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

bug in strcpy

I have the following structure:

struct fence_struct	{
  unsigned char	mode;
  char		sitename[13];
  unsigned char	sector_nr;
  unsigned char	sector_tot;
  unsigned int	start;
  unsigned int	feeder_offset;
  unsigned int	len;
  unsigned int	line_len;
  unsigned char	begin_far;
  unsigned int	res_norm;
  unsigned int	res_min;
  unsigned int	res_max;
  unsigned char	wire_amount;
  unsigned char	wire_name[12];
};

xdata struct fence_struct  fence;

I then initialise fence.sitename like this in the function init_vars():
strcpy(fence.sitename, "SITENAME");

and it generates this assembly:
;strcpy(fence.sitename, "SITENAME");
;SOURCE LINE # 1535
MOV  	R0,#LOW (fence+01H)
MOV  	R4,#HIGH (fence+01H)
MOV  	R5,A
MOV  	R3,#0FFH
MOV  	R2,#HIGH (?SC_403)
MOV  	R1,#LOW (?SC_403)
LCALL	?C?STRCPY

WHICH DOESN'T WORK

However, when I call exactly the same line in the function misc_info() it generates the following assembly:
;strcpy(fence.sitename, "SITENAME");
;SOURCE LINE # 4306
MOV  	R0,#LOW (fence+01H)
MOV  	R4,#HIGH (fence+01H)
MOV  	R5,#01H
MOV  	R3,#0FFH
MOV  	R2,#HIGH (?SC_403)
MOV  	R1,#LOW (?SC_403)
LCALL	?C?STRCPY

WHICH WORKS FINE

Why does it generate different assembly for the same source line and how can I rectify it?

Parents

  • The DS5000T uses NVRAM with a on-board lithium cell. It also has a built-in boot loader. You place it in Program mode by taking the RST pin high and the PSEN pin low simultaneously.
    Pgm mode is ended when "power is removed from the device or when the Program Load configuration strapping (RST=1, PSEN=0) is removed".
    "If the Program Load configuration strapping is removed with power still applied at Vcc, the device will undergo an internal hardware reset and will begin executing code from the reset vector location at 0000H in Program Memory."


    --> So you see an exit from pgm mode is supposed to behave the same as a power-up. Therefore I cannot explain why the 1st call only executes properly with a power-up.

    I know initialization #1 gets executed because all the other lines of that function gets executes and there's no branches.

    When I say "incorrect initialization" it means a bunch of garbage is displayed on the LCD when I printf() the string. Also it prints over other text which indicates the string is not terminated with a NULL.

    I hope this answers you questions.

Reply

  • The DS5000T uses NVRAM with a on-board lithium cell. It also has a built-in boot loader. You place it in Program mode by taking the RST pin high and the PSEN pin low simultaneously.
    Pgm mode is ended when "power is removed from the device or when the Program Load configuration strapping (RST=1, PSEN=0) is removed".
    "If the Program Load configuration strapping is removed with power still applied at Vcc, the device will undergo an internal hardware reset and will begin executing code from the reset vector location at 0000H in Program Memory."


    --> So you see an exit from pgm mode is supposed to behave the same as a power-up. Therefore I cannot explain why the 1st call only executes properly with a power-up.

    I know initialization #1 gets executed because all the other lines of that function gets executes and there's no branches.

    When I say "incorrect initialization" it means a bunch of garbage is displayed on the LCD when I printf() the string. Also it prints over other text which indicates the string is not terminated with a NULL.

    I hope this answers you questions.

Children
  • Is it possible that your program changes the MCON register in a way that affects the partition address. And, after you exit program mode, the first time the program runs, the partition address is changed. Then, after a cold start, since the partition address is set correctly, everything works OK?

    Since you are using a DS5000, your XDATA starts at the partition address. Have you specified it that way to the linker?

    Jon

  • I've checked that I don't write to the MCON register anywhere in my code. I only write to it after the hex file has been loaded into pgm mem while the MCU is still in Pgm mode.

    Yes, I specify in Keil that the Code mem is from 0x0000-0x6FFF and the Xdata mem is from 0x7000-0x7FFF.

    I've also noticed that a second reset (after the 1st which took it out of pgm mode) has the same effect as a cold start.

  • OK, so the state of this analysis is that probably the content of the Accu is not the expected 01H if your routine number 1 is called as the consequence of a "going out of PGM mode" condition.

    Among other things, this just might be a hardware bug.

    Without seeing a lot more of your code (or a smaller, self-contained example case that still shows the problem), it'll be quite impossible for anyone but yourself to debug this further. You may have to use an ICE or logic analyser to see what the CPU actually does.

    (BTW: does it work in the Keil simulator?)

  • Well,

    If the program works after a cold start, I seriously doubt that there is a compiler or code generation problem. In fact, I'd start looking at the state of the device after exiting programming mode.

    However, since your device PROBABLY won't be programmed (in the field) and immediately started running (in the field) I don't think this is a critical issue. I mean, you are going to load the program into the device and send it somewhere (probably unpowered). Once it gets to its destination and powered-up, everything will work fine (since cold starts work OK).

    Jon

  • I agree with you: The fact that it initialises the variables correctly after a cold start or after the 2nd reset shows to me that, contrary to what the datasheet says, the DS5000T DOES NOT execute a complete reset after it's taken out of pgm mode.

    But then again, why does it initialise the numerical variables before and after the strcpy() in question correctly but not the strcpy() itself??