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

Checksum being skipped in the loader.c?

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



Joined: 20 Jul 2011
Posts: 60

View user's profile Send private message

Checksum being skipped in the loader.c?
PostPosted: Mon Aug 22, 2011 9:45 pm     Reply with quote

Hi Everyone -

Though I am highly considering a go at EdWaugh's code, I have invested quite a bit of time into the CCS example bootloader and would like to "go the distance" with it.

I am monitoring the flow of data from the hex file and using printf to see where I am in the code. I have allocated a decent chuck of memory for the real_load_program function. The hex file is approx. 40 lines

The incoming hex data is being buffered and it is clearing the IF statement to determine if a colon ( : ) is present on the first line.

However, it looks as though the checksum code never sees the light of day. I may be stomping on something.

BUT, I am really curious about a piece of code that befuddles me. I have spent a good deal of time pouring through the loader.c to understand its operation.

This code appears just before checksum code. Even if this does not resolve my issue with the checksum, I would really like to know what it does:

Code:

         if (line_type == 1) {
            done = TRUE;
         #if defined(__PCM__)
         } else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x2000){
         #elif defined(__PCH__)
         } else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x300000){
         #endif


There seems to be a progression of IF statements. I would tend to assume that if none of them are met, the code should go on. I have to admit that I have never seen IF statements assembled in this fashion.

Regards -

RckRllRfg
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Aug 23, 2011 12:32 am     Reply with quote

Quote:
I have to admit that I have never seen IF statements assembled in this fashion.

Do you understand the difference between the C code if statements and the preprocessor #if?

When the preprocessor has parsed the text, only a single else if remains, e.g. for PCH:
Code:
if (line_type == 1) {
  done = TRUE;
  } else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x300000){
  checksum = 0;  // Sum the bytes to find the check sum value

It's B.T.W. not "the checksum code" rather than the regular processing of those hex-file parts, that fall within in the intended address range.
RckRllRfg



Joined: 20 Jul 2011
Posts: 60

View user's profile Send private message

PostPosted: Tue Aug 23, 2011 7:37 am     Reply with quote

FvM -

I do know the difference between the if and the #if; however, I was getting confused by trying to read the code all at once. Your example is excellent - I should have striped out the precompiler info which would have made it more readable. What was really tripping me up were the order of the parentheses.

Thank for you help -

RckRllRfg
RckRllRfg



Joined: 20 Jul 2011
Posts: 60

View user's profile Send private message

Memory Stomping that is causing it
PostPosted: Thu Aug 25, 2011 12:51 am     Reply with quote

Update to this posting. I found that I am having a problem with memory stomping. (Working on a bootloader.) That is why I was never seeing this piece of the code working.
RckRllRfg



Joined: 20 Jul 2011
Posts: 60

View user's profile Send private message

Clarification .... for the 16F1947 bootloader issue
PostPosted: Fri Sep 09, 2011 10:50 am     Reply with quote

Upon much further research, this was not a memory stomping. There is a recently discovered issue with the CCS function write_program_memory(). I hope that CCS does not mind me posting this; however, I've lost 2 weeks digging this out and chasing false leads on the ex_bootloader. (ie, checksums, hex address values, and the make16 function have all been falsely accused, interrogated, and found "not guilty")

From CCS support:
Quote:

" The problem may be due to an error in the write_program_memory() function for this PIC [16F1947] that causes it to take longer to execute when only writing the first 8, 10, 12 or 14 bytes of a write row. This bug doesn't keep the function from working it only causes it to take much longer to execute then it should. My test showed that when I tried writing 8, 10, 12 or 14 bytes in a row it was taking approximately 390 ms to write the row, when it should only take approximately 12 ms to write the row. Since your terminal program is only waiting 300 ms between lines and the multiply delays you have in your code, I believe the UART is being shutdown due to a buffer overrun causing the code to get stuck. I have fixed the bug with write_program_memory() and it will be available in the next compiler release. Until then I would recommend increasing the wait time between lines of your terminal program to at least 500 ms."


Note that the compiler being used is 1.124.

I'll post my original inquiry momentarily....


Last edited by RckRllRfg on Fri Sep 09, 2011 10:54 am; edited 1 time in total
RckRllRfg



Joined: 20 Jul 2011
Posts: 60

View user's profile Send private message

original inquiry
PostPosted: Fri Sep 09, 2011 10:52 am     Reply with quote

I originally thought that this has to do with the length of the hex file and the total memory use of the application program; however, this is not so, as my experiments suggest. What I have found is that the 4th to the last line (minus the final comments) is where the bootloader seems to get tangled.

EX:

:100DA0009200031004302000C200E4240000D72E7B <--This line seems iffy, depends on length
:020000040001F9
:04000E00E219FF0FE5
:00000001FF
;PIC16F1947
;CRC=55D0 CREATED="05-Sep-11 23:32"

In my experiments, I added a nop to the code to adjust the size of the 4th to last line of the hex code. I continued to add another NOP to see the results. Though this is in the sample code attached, here are the following results:

// Up to this point, the end hex is 0E, which did not work

nop; //00 - Worked :100DA0009200031004302000C200E4240000D72E7B
nop; //02 - Worked :020DB000D82E3B
nop; //04 - Worked :040DB0000000D92E38
nop; //06 - Worked :060DB00000000000DA2E35
nop; //08 - No Go :080DB000000000000000DB2E32
nop; //0A - No Go :0A0DB0000000000000000000DC2E2F
nop; //0C - No Go :0C0DB00000000000000000000000DD2E2C
nop; //0E - No Go :0E0DB000000000000000000000000000DE2E29
nop; //10 - Worked :100DB0000000000000000000000000000000DF2E26
nop; //12 - Worked :020DC000E02E23
nop; //14 - Worked :040DC0000000E12E20
nop; //16 - Worked :060DC00000000000E22E1D
nop; //18 - No Go :080DC000000000000000E32E1A
nop; //1a - No Go :0A0DC0000000000000000000E42E17
nop; //1c - No Go :0C0DC00000000000000000000000E52E14
nop; //1e - No Go :0E0DC000000000000000000000000000E62E11
nop; //20 - Worked :100DC0000000000000000000000000000000E72E0E


If the 4th to last line has a data count of 2h,4h,6h or 10h, then the bootloader will process this correctly; otherwise it will hang. It does seem to damage/stomp the bootloader (ie, I need to reprogram it for the bootloader to recover.)

As for the code itself, the changes that I have made:

1) Reallocated in terms of location and size of the memory locations
2) Added delay_ms commands, which I have to have due to use of the half duplex mode
3) Added putchar statements as a debug.
4) Total allocation is 0 to 3FF (and I'm not too worried about space)

Using:
1) Pic16F1947, revision 2 of the silicon
2) Microchip ICD2 with modifications to prevent overvoltage since max VPP of 1947 is less than the voltage sourced by the ICD2
3) CCS compiler 1.124 (also tried 1.123 without change)
4) Using MPLAB 8.76 as the host for the compiler
5) Using RealTerm to monitor and send hex data. Have used it on Tera Term and have seen the same result. Have a delay of 5ms/char and 300ms/EOL
6) Half duplex mode. Currently using RS485, though I can switch it to RS232
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Sep 09, 2011 1:04 pm     Reply with quote

I must confess, a similar problem could be already guessed from your last post in your other thread realted to this problem. http://www.ccsinfo.com/forum/viewtopic.php?t=46215

Unfortunately I'm not using this processor nor a PIC16 bootloader at all. I'm sure, that the problems shows immediately up, when you trace bootloader operation with a hardware debugger. But you need the hardware.
linera



Joined: 23 Nov 2011
Posts: 6

View user's profile Send private message

PostPosted: Wed Jul 25, 2012 6:07 am     Reply with quote

RckRllRfg, I would like to know why you say " It looks as though the checksum code never sees the light of day".
I am working with the original ex_bootloader.c, loader.c and ex_bootload.c files.
Well, there is a little difference in the ex_bootloader.c file. I have changed something of the main application part:
Code:
#if defined(__PCM__)
 #org LOADER_END+1,LOADER_END+50
#elif defined(__PCH__)
 #org LOADER_END+2,LOADER_END+20
#endif
void application(void) {
   while(TRUE){
      output_toggle(PIN_B0);
      delay_ms(1000);
    }   
}

This is not an important difference with respect to the original file.
My problem is when I try to charge the new hex file using the bootloader.

After I send the first line of the hex file, the checksum verification does not work well in the loader.c file.
The problem is this line:
Code:
       if (checksum != atoi_b16 (&buffer[buffidx-3]))

When it call to the atoi_b16 function, it must pass the address of the buffer where the cheksum of the line is stored (buffidx-3). In the watch window, I can see that this position must be 0x4C (in my case with a PIC16F877), but when I debug, I can see that the passed address is not the right one.
This problem is solved if I change the previous line of the loader.c file with this other:
Code:
   checksumidx=buffidx-3;
            //if (checksum != atoi_b16 (&buffer[buffidx-3]))
   if (checksum != atoi_b16 (&buffer[checksumidx]))

where checksumidx is an integer variable defined at the beginning of the file. Checksumidx get the value 0x4C that is the right address of the checksum in the buffer and so, the recpetion of the line is OK and it is written to the EEPROM.
Can you understand which is the difference between both solutions and why the second one works fine and the first one no?

Other thing more, to complicate a little more my question:
If I use the first solution
Code:
       if (checksum != atoi_b16 (&buffer[buffidx-3]))

but when I define the variables, I put this:
Code:
int  buffidx,checksumidx;

instead of
Code:
int  buffidx;


The checksum verification works OK.
The only difference is that I define the variable checksumidx after buffidx, although i never use the variable checksumidx in the file.

Someone can explain me this? Is a problem with the compiler?

Sincerely
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