|
|
View previous topic :: View next topic |
Author |
Message |
naughty_mark
Joined: 29 Aug 2012 Posts: 97
|
Problem with dsPIC30F6014A bootloader |
Posted: Wed Jun 11, 2014 12:14 am |
|
|
Hi everyone,
I got a problem with dsPIC30F6014A micro with CCS compiler v5.016.
I use the bootloader code that CCS provides, its name is "ex_bootloader.c" with minimum changes. For give a full picture, I list those minimum changes even that is not the root cause of my problem. Changes are:
a. when get address 0x0000, record that RESET goto address into E2 so that program can read the value from E2 when power on and enter main program if there is no bootloader triggered. The reason I did that is I failed to use CCS way to let micro grab the entry address of main program automatically. That way works anyway.
b. send pos/neg feedback when got hex code from PC side, so the bootloader can run under higher baudrate with re-send strategy for stabilization.
On PC side, I program a simple hex file sender with re-send strategy by VC++, and it works well.
For my project, there are two firmware : full version and cutdown version using one same hardware. After I programed my bootloader code into the uC with PIC kit3, they are both working if those firmware is the first one to downloaded by bootloader. Which means after bootloader programmed, if I use it to download full version firmware firstly, full version works very well. If download cutdown version firmware firstly, cutdown version works well. However, if the firmware is downloaded at the second time or say not first time by using bootloader, it doesn't work. For example, after I programmed bootloader, then I use bootloader to download full version firmware, full version works. Then I use bootloader again to refresh the main program from full version to cutdown version, the cutdown version doesn't work. It is same if the order is reversed. Some points I already check and make sure they are fine:
a. The bootloader code in uC is fine, it is not corrupted while downloading the main firmware.
b. the corrupted firmware doesn't work or say partly work precisely, because it can implement ini hardware and ini my application, but can not run the timer based RTOS which I called scheduler function. Then I suspect either the entry address of "scheduler" function is corrupted or the interrupt vector is corrupted which leads the system time ticker not working.
Comparing with data of the working cutdown version firmware with not working one by reading program memory via PIC kit3, I found the address from 0x00006 to 0x00003E are corrupted, they are not same. The data from working sample is the same as HEX file, and the data from not working sample is not the same as HEX file. I even just cut these part hex file into a separate hex file and use bootloader just download this interrupt vector part, but the same result.
Is there anyone having this problem before, or is there something wrong I did.
Sorry for this Loooooong thread, I just wanna make clear to you guys and tell you what I checked and got.
I do appreciate you guys' help.
Kind Regards
Mark
EDIT:
More I got. As I said I just cut out this part in HEX to form a separate HEX file as below:
Code: |
:0800000094AA040000000000B6
:04000C00805600001A
:100010008057000080560000805600008056000087
:1000200080560000805600008056000058560000A0
:100030008056000080560000805600008056000068
:10004000805600008056000080560000D05300000B
:100050008855000080560000805600008056000041
:100060008056000080560000805600008056000038
:10007000805600008056000080560000D6550000D3
:10008000FA5500008156000080560000805600009E
:100090008056000080560000805600008056000008
:1000A00080560000805600008056000080560000F8
:1000B00080560000805600008056000080560000E8
:1000C00080560000805600008056000080560000D8
:1000D00080560000805600008056000080560000C8
:1000E00080560000805600008056000080560000B8
:1000F00080560000805600008056000080560000A8
:00000001FF
;DSPIC30F6014A
|
As you can see, before address 0x0003E, it is 008056 in hex and must be 005680 in program memory, and I changed the one at address 0x0008 to 8057, and changed "8056" just next to pattern "FA55" to "8156", and changed the checksum on those two lines. And then use bootloader to program it then I read out the data in uC program memory, the 8057 does No effect (no changes)but 8156 does(changed to 5681)...... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19490
|
|
Posted: Wed Jun 11, 2014 6:49 am |
|
|
I suspect your problem is with your approach, and 'pages'.
Since your code allows the target address of the main code to change, you have to change the data stored at address 0. This means you have to rewrite the page at the base of memory. You therefore need to _read_ the entire page at this address, change just the vector, and then write back the whole page.
Unless you do this, the rest of the first page will be corrupted.
Realistically, it is simpler, and safer, to use the CCS approach.
Reserve the memory amount corresponding to the larger bootloader, and make your code compile to reside above this address. Then the start address can remain unchanged, and (more importantly for long term safety), you can have the bootloader refuse to program any page that comes into it's resident area, and preferably enable the code protect on this area. |
|
|
naughty_mark
Joined: 29 Aug 2012 Posts: 97
|
|
Posted: Wed Jun 11, 2014 4:40 pm |
|
|
Ttelmah wrote: | I suspect your problem is with your approach, and 'pages'.
Since your code allows the target address of the main code to change, you have to change the data stored at address 0. This means you have to rewrite the page at the base of memory. You therefore need to _read_ the entire page at this address, change just the vector, and then write back the whole page.
Unless you do this, the rest of the first page will be corrupted.
Realistically, it is simpler, and safer, to use the CCS approach.
Reserve the memory amount corresponding to the larger bootloader, and make your code compile to reside above this address. Then the start address can remain unchanged, and (more importantly for long term safety), you can have the bootloader refuse to program any page that comes into it's resident area, and preferably enable the code protect on this area. |
Thanks for your reply, Ttelmah. I also doubt if there is a page erase happened, but I didn't keep tracking this way because the flash erase size is 128, and the fact is the data only corrupted under address 0x0003E, after that are fine. The reason why I use that way to figure out main program entry address is in a thread, a little long story actually, I don't know if I did something wrong or the compiler not support this uC well. The thread is
http://www.ccsinfo.com/forum/viewtopic.php?t=51902&postdays=0&postorder=asc&highlight=bootloader+mark&start=0
And when the bootloader gets data at 0x0000 address which is the main program entry address, it will implement
Code: | if(addr == 0)
{
myAppAddr = (((unsigned int32)data[3]) << 24)
| (((unsigned int32)data[4]) << 16)
| (((unsigned int32)data[1]) << 8)
| ((unsigned int32)data[0]); write_eeprom(E2_MY_APP_ADDR,&myAppAddr,4);
delay_ms(20);
}
|
as you can see, it won't implement ROM write operation, just record the entry address in E2PROM.
EDIT: I just tried the thread I mentioned above again, in the main program, I add
Code: |
#build (RESET = 0x0900, INTERRUPT = 0x0904)
#ORG 0x0000,0x08FF {}
|
and I changed my bootloader code a little bit to fit in that change, Now if no bootloader trigger, program pointer will jump to 0x0900. I checked the hex file of main program, the address location starts from 0x0900, and interrupt vector moved to 0x0904, but when I power on, I only have welcome picture and then reset again and again, which means the main program only finish ini hardware and ini Application and can not go into the sheduler function. I use "restart_cause()" function, the value is 15, it is confilct trap cause this resets. So with CCS traditional way, even the first time downloading get failed. |
|
|
|
|
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
|