CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC program code gets corrupted/changed

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PIC program code gets corrupted/changed
PostPosted: Tue Apr 22, 2008 9:31 am     Reply with quote

Hi readers,

I'm having this major problem; the PIC program's code gets corrupted/changed in some way. The board starts up normally but then USART routine to isn't working anymore.
I've also had some boards (PIC's) that even didn't start anymore.

I know it is a software problem because I can reprogram the bootloader in the PIC's flash and then reprogram it, and after that my program works again. It does not happen a lot. It's happened in I guess 10 out of 100 boards.

Some specs:
- I use a bootloader which is at upper memory.
- I have a PIC16LF877A

I don't know how I can debug this, your advice please.
- What can be theoretically the cause of the code getting changed?
- What can I do to prevent this?
Matro
Guest







PostPosted: Tue Apr 22, 2008 9:40 am     Reply with quote

I have such a problem because I programmed my PIC powered by the board power supply that was an isolated one.
So there was GND problems.

Matro.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Wed Apr 23, 2008 12:49 am     Reply with quote

I don't think it's a programming problem as my boards initially get programmed OK. They worked OK.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 23, 2008 1:07 am     Reply with quote

Quote:

I know it is a software problem because I can reprogram the bootloader
in the PIC's flash and then reprogram it, and after that my program
works again.

I don't see how that makes it a software problem. It could be software
or hardware. In other words, the flash is getting erased or glitched.
The cause of that could be in hardware or software.

Do the same boards always fail ?
If so, get rid of the bootloader on those boards. Also get rid of any
other code that writes to flash program memory. If these boards now
start working, then maybe you have a problem with the bootloader
routine being accidently called when power is turned on to the PIC.

Use your programmer to read the flash memory of the PICs that
have failed. Compare it to a good image. What data is written to
the damaged area in the program memory ? Is it 0x3FFF ? Or
something else ? Can you tell if the bootloader is doing the writing ?

Hardware questions:
1. What is the Vdd voltage for the PIC ?

2. What is the crystal frequency ? Are you using a crystal ?
If so, what is the value of the load capacitors ?

3. Do you have a 100 nF ceramic capacitor between each Vdd pin
and ground ? Are they placed very close to the PIC ?

4. Are you using a voltage regulator for the Vdd voltage ?
If so, do you have a 10 uF tantalum capacitor on the output ?

5. What is the value of the pull-up resistor on the MCLR pin ?

6. What is the ambient temperature when the PICs fail ? Are they
kept at room temperature all the time ?
Matro
Guest







PostPosted: Wed Apr 23, 2008 1:43 am     Reply with quote

I'm gonna add this question :

How is powered your PIC during programmation (type of supply, wiring, ...)?

Matro.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Wed Apr 23, 2008 2:06 am     Reply with quote

Hi, thanks for getting deeper into this.

PCM programmer wrote:
Quote:

I know it is a software problem because I can reprogram the bootloader
in the PIC's flash and then reprogram it, and after that my program
works again.

I don't see how that makes it a software problem. It could be software
or hardware. In other words, the flash is getting erased or glitched.
The cause of that could be in hardware or software.

- What possible hardware causes are there?

Quote:

Do the same boards always fail ?
If so, get rid of the bootloader on those boards. Also get rid of any
other code that writes to flash program memory. If these boards now
start working, then maybe you have a problem with the bootloader
routine being accidently called when power is turned on to the PIC.

No, I can't say when it happens. When I reprogram them, they are fine and the program works again.
I'm also thinking that it might be possible that the bootloader routine is getting called accidentally; it's activated by receiving 2 X the same character. These characters have to be sent by another processor.
The bootloader code is:

Code:

// Include gogoloader.h in main program
// #ORG LOADER_BEGIN, LOADER_END {} in main program
#include <16F877A.H>
#device *=16
//#case
#fuses XT, PUT, NOWDT, NOPROTECT, NOLVP, NOCPD, NOWRT, NOBROWNOUT
#define READY_FOR_NEXT  0x11                                   // define possible reply bytes
#define FINISH_FLAG     0x55
#define BOOTLOADER_OVERWRITE  0x80
#define SerBufferSize 45                                       // serial input buffer size

#include "GOGOLOADER.H"
#ORG LOADER_BEGIN, LOADER_END auto=0 default                   // #org tells the compiler where to put the procedures in memory
#use DELAY (clock=4000000)
#use rs232 (baud = 19200, parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

unsigned int a2i (unsigned char asciiByte)                     // a slim version of atoi().converts ascii text to integer
{                                                              // i.e. '1' = 1, 'A' = 10
      if (asciiByte >= 'A' && asciiByte <= 'F')
         return((asciiByte) - 'A' + 10);
      else if (asciiByte >= '0' && asciiByte <= '9')
         return ( asciiByte - '0');
}

unsigned int read8 ()
{                                                              // convert two ascii text to a 8 bit integer
     return( (a2i(getc()) << 4) + (a2i(getc())) );
}

void main ()
{
   unsigned int16 Buffer[SerBufferSize];                       // serial input buffer
   int1 notDone = 1, CODE_TOO_LARGE = FALSE;
   unsigned int recLen;                                        // HEX file record length
   unsigned int16 writeAddr, timeout = 0;                          // HEX file write address
   unsigned char recType;                                      // HEX file record type
   unsigned char i=0,j, triggers_found = 0;                    // general counters
   unsigned int16 UserBootVectorAddr;                          // holds the address of our new boot vector
   unsigned int16 User_BootVector [4] = { 0,0,0,0 };

   for ( i = 2; i > 0 ; i-- )
   {
      while ( !kbhit () && (++timeout < 0xFFFF) )               // 2 Seconden tijd om downloadcommando te sturen: 0xAA , 0xAA
         delay_us (16);

      if ( kbhit () )
      {
         if ( getc () == 170 )
            triggers_found++;
         else
            break;
      }
   }

   if ( triggers_found == 2 )
   {
      putc ('L');
      UserBootVectorAddr=label_address(UserBootVector);           // Get the adress in the bootloader where the reset vector will be

      while (notDone)
      {
         while (getc() != ':') ;                                  // Wait for ':'
         recLen = read8();                                        // Hex file Record length
         recLen >>= 1;                                            // we divided the Length by 2.
                                                                  // Each memory location on the PIC (16 bit) is
                                                                  // twice the unit size of the HEX file (8 bit).
         writeAddr  = ((int16)read8() << 8) + read8();            // Write Address
         writeAddr >>= 1;                                         // divide by 2
                                                                  // The physical address on the PIC is half the address in the HEX file.
         getc ();                                                 // ignore the first digit, it is always '0'
         recType = getc();                                        // Get the Rec Type

         if (recType == '1')                                      // End of file record
            notDone = 0;
         else if (recType == '0')                                 // data record: get the data
         {
            for (i=0; i < recLen ; i++)
                Buffer[i] = read8() + ((int16)read8() << 8);

            if ((writeAddr >= 0x2100) && (writeAddr <= 0x21FF))      // if data is in the EEPROM area
               write_eeprom((int) writeAddr, (int) Buffer[i]);

            else if ((writeAddr >= 0x2000) && (writeAddr <= 0x20FF)) // else if data is in the Configuration register area
            {}                                                        // Can't write configuration registers -> just skip.

            else if ( (writeAddr >= LOADER_BEGIN) && (writeAddr <= LOADER_END))   // else if data overlaps the bootloader code -> halt
            {
               CODE_TOO_LARGE = TRUE;
               break;
            }
            else
            {                                                      // else -> data is in program area
               for (i=0; i < recLen ;i++)
               {
                  if (!CODE_TOO_LARGE)
                  {
                     if ((writeAddr < 0x004) && (i<4) )
                {
                   User_BootVector[i] = Buffer[i];
                }
                     else
                        write_program_eeprom (writeAddr + i, Buffer[i]);
                  }
               }
            }
            putc (READY_FOR_NEXT);                                // Tells the PC to send the next line
         }
      }
      if ( CODE_TOO_LARGE )
         putc ( BOOTLOADER_OVERWRITE );
      else
      {
         for ( i=0; i < 4 ;i++)
              write_program_eeprom (UserBootVectorAddr + i, User_BootVector[i] );
         putc ( FINISH_FLAG );                                    // Tells the PC that we are finished
      }
      for (j=0;j<255;j++)                    // this loop gives the chip time to finish sending the serial byte before resetting it self.
      {
         for (i=0;i<255;i++) {};
      }
      //delay_ms ( 2 );
   } // While notdone

UserBootVector:
#asm                          // This is a reboot command written in Assembly.
      MOVLW   0x00                  // these four commands will be overwritten with the boot vector we obtain from the HEX file.
      MOVWF   0x0A
      GOTO   0x00
      NOP
      NOP
#endasm
}// main
#ORG default


Quote:

Use your programmer to read the flash memory of the PICs that
have failed. Compare it to a good image. What data is written to
the damaged area in the program memory ? Is it 0x3FFF ? Or
something else ? Can you tell if the bootloader is doing the writing ?

I did that. There are not many differences.
file 1 (OK): http://users.[spam].be/chs/Werk/BOOTLOADER_PIC_2_4_IMAGE.HEX
file 2 (corrupted): http://users.[spam].be/chs/Werk/BOOTLOADER_PIC_2_4_IMAGE_ACQUET.HEX

How can you tell the bootloader is doing the writing?

Quote:

Hardware questions:
1. What is the Vdd voltage for the PIC ?

That is 3V, I have a PIC16LF877A.

Quote:

2. What is the crystal frequency ? Are you using a crystal ?
If so, what is the value of the load capacitors ?

I have a ceramic resonator, it has capacitors built in.

Quote:

3. Do you have a 100 nF ceramic capacitor between each Vdd pin
and ground ? Are they placed very close to the PIC ?

Yes, 1 at each Vdd pin + 1uF + 47uF electrolytic cap, for voltage stability.

Quote:

4. Are you using a voltage regulator for the Vdd voltage ?
If so, do you have a 10 uF tantalum capacitor on the output ?

Yes a TI TPS78930; it has 4u7 at the output.

Quote:

5. What is the value of the pull-up resistor on the MCLR pin ?

http://users.[spam].be/chs/Werk/mclr_circuitry.jpg
But recently I've changed it to a 33Kohm pullup close to the PIC and a 2k2 series resistor + 1nF/50V filter cap on MCLR. However the failing boards have the circuitry as shown in the link.

Quote:

6. What is the ambient temperature when the PICs fail ? Are they
kept at room temperature all the time ?

That is room temperature.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Thu Apr 24, 2008 6:42 am     Reply with quote

Any advices?

- Is it possible the code gets corrupted changed, when there is a low battery situation, like a grey zone for the PIC supply voltage..
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 24, 2008 11:23 am     Reply with quote

I still have to look at it some more. But I have a basic philosophy
on fixing unknown problems. Everything that you are doing that is
different from the "baseline", should changed so it is same as the
baseline. Examples:

1. You're using a bootloader. Don't use it. Remove the code for it.
I assume you're using surface mount PICs. Can the PICs be
re-programmed with an ICD2 by the ICSP method ? Are the boards
setup for that ? If so, design a version of your code that does not use
the bootloader. Run several boards with it and see if the failure stops.
If so, you have found the basic problem and you can work on it.

2. You're running a resonator. Use a crystal (and capacitors) instead.

3. You're running at 3v. Try running it at 5v instead.

4. You're using a 16F877A. Use the "non-A" version instead.
The "A" version was always more sensitive to power supply noise than
the original non-A version.

5. You're using the "LF" version. When you run it at 5v, you could also
switch to the "non-LF" version.

6. Board layout can be important. If you're using a 2-layer board
without a gridded power and ground layout, then change it to a 4-layer
board, or grid the power and ground. Don't put the PIC's power and
ground pins at the end of a stub trace. Those pins must be right on top
of a main power or ground trace. A "stub" is like a cul-de-sac street.
Avoid stubs. They create a lot of noise on the power and ground pins.

7. You're using a unusual MCLR circuit. Change to a standard circuit.
Quote:
However the failing boards have the circuitry as shown in the link.

The 390K is a mistake. That's too high of an impedance. I would
reduce it to 10K. Get rid of all the other components in the MCLR circuit
and just use the 10K pullup. Do this on all the failing boards and see
if it fixes the problem.


You don't have to do all of these things at once. Maybe just do the last
one, with the MCLR circuit, because I think it might be the best bet.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Fri Apr 25, 2008 4:03 am     Reply with quote

Hi, thanks for replying.

PCM programmer wrote:
I still have to look at it some more. But I have a basic philosophy on fixing unknown problems. Everything that you are doing that is different from the "baseline", should changed so it is same as the baseline. Examples:


I know, some things are different. The problem is I can't change that much. The board is allready in production.

Quote:

1. You're using a bootloader. Don't use it. Remove the code for it.
I assume you're using surface mount PICs. Can the PICs be
re-programmed with an ICD2 by the ICSP method ? Are the boards
setup for that ? If so, design a version of your code that does not use
the bootloader. Run several boards with it and see if the failure stops.
If so, you have found the basic problem and you can work on it.

I could do that, but the bootloader gives me the advantage to program the PIC processor with having to open the device and plugin the programmer which is very extensive.
It's a good idea to find out whether the bootloader is the cause.

Quote:

2. You're running a resonator. Use a crystal (and capacitors) instead.

I saw you write this alot; why is a X-tal better?

Quote:

3. You're running at 3v. Try running it at 5v instead.

That's impossible with the current design. 3V3 however would be possible. Would that be better?

Quote:

4. You're using a 16F877A. Use the "non-A" version instead.
The "A" version was always more sensitive to power supply noise than
the original non-A version.
5. You're using the "LF" version. When you run it at 5v, you could also
switch to the "non-LF" version.

I'm planning to change the MCU after reading this: http://www.ccsinfo.com/newsdesk_info.php?newsPath=ALL&newsdesk_id=91

Quote:

6. Board layout can be important. If you're using a 2-layer board
without a gridded power and ground layout, then change it to a 4-layer
board, or grid the power and ground. Don't put the PIC's power and
ground pins at the end of a stub trace. Those pins must be right on top
of a main power or ground trace. A "stub" is like a cul-de-sac street.
Avoid stubs. They create a lot of noise on the power and ground pins.

See this topic for more info about board layout. I have 3 boards stacked. http://www.ccsinfo.com/forum/viewtopic.php?t=33300&highlight=
As you can read, I also have random reset problems.

Quote:

7. You're using a unusual MCLR circuit. Change to a standard circuit.
However the failing boards have the circuitry as shown in the link. The 390K is a mistake. That's too high of an impedance. I would
reduce it to 10K. Get rid of all the other components in the MCLR circuit
and just use the 10K pullup. Do this on all the failing boards and see
if it fixes the problem.


I've changed this in the newest revision of the boards:
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group