|
|
View previous topic :: View next topic |
Author |
Message |
Christophe
Joined: 10 May 2005 Posts: 323 Location: Belgium
|
PIC program code gets corrupted/changed |
Posted: Tue Apr 22, 2008 9:31 am |
|
|
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
|
|
Posted: Tue Apr 22, 2008 9:40 am |
|
|
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
|
|
Posted: Wed Apr 23, 2008 12:49 am |
|
|
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
|
|
Posted: Wed Apr 23, 2008 1:07 am |
|
|
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
|
|
Posted: Wed Apr 23, 2008 1:43 am |
|
|
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
|
|
Posted: Wed Apr 23, 2008 2:06 am |
|
|
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
|
|
Posted: Thu Apr 24, 2008 6:42 am |
|
|
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
|
|
Posted: Thu Apr 24, 2008 11:23 am |
|
|
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
|
|
Posted: Fri Apr 25, 2008 4:03 am |
|
|
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:
|
|
|
|
|
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
|