View previous topic :: View next topic |
Author |
Message |
Swys
Joined: 24 Feb 2010 Posts: 22
|
Write to 0x00 erases memory? |
Posted: Wed Jun 02, 2010 7:02 am |
|
|
Hi all,
I am almost done writing a bootloader, save for this problem I'm having...
I wrote a small program to flash an LED which I then load into the PIC with my bootloader. Everything goes fine, until it tries to write to the first two locations in memory (the GOTO instruction at 0x00 and the Reset address). When I attempt this, everything I've just written gets wiped out.
My bootloader resides at the end of the program memory. When it starts, it backups the data at two memory addressess mentioned (0x00 and 0x02) and erases all the data (except for the bootloader, of course). Then, it writes the firmware received from the UART and afterwards attempts to restore the data at 0x00 and 0x02, so that the PIC will automatically jump to the bootloader upon reset. After this, the bootloader jumps to the user program.
When I comment out the two lines to write to 0x00 and 0x02, the loaded firmware is run correctly but, of course, the PIC doesn't know where to go to after a reset.
I am using the PIC24HJ128GP502 for development with version 4.107 of the PCD compiler.
Here is the test program I wrote as well, if it will be of any help. The #build(reset = 0x200) is so that I know exactly where to jump to from the bootloader:
main.c
Code: |
#include "main.h"
#include "bootloader.h"
#define LED PIN_B6
#build(reset = 0x200)
#ORG LOADER_START_ADDR, LOADER_END{}
void main()
{
while (1)
{
output_toggle(LED);
delay_ms(100);
}
}
|
bootloader.h
Code: |
#ifndef BOOTLOADER_H
#define BOOTLOADER_H
#define LOADER_END getenv("PROGRAM_MEMORY") - 1
#define LOADER_SIZE 0x7FF //2kB
#define LOADER_START_ADDR LOADER_END - LOADER_SIZE
#endif
|
|
|
![](templates/subSilver/images/spacer.gif) |
Gary Smithson
Joined: 13 Feb 2004 Posts: 22
|
|
Posted: Wed Jun 02, 2010 10:40 am |
|
|
Remember that write_program_memory () automatically erases blocks when the first address of that block is written to. This is described in the compiler help file. Address 0x0000 would be the beginning of a block so when you re-write the reset vector, the leading chunk of your newly bootloaded program is getting erased.
Since you are manually erasing memory before the bootload, you should probably be using write_program_eeprom (), which does not automatically erase blocks.
Hope that helps,
Gary |
|
![](templates/subSilver/images/spacer.gif) |
Swys
Joined: 24 Feb 2010 Posts: 22
|
|
Posted: Thu Jun 03, 2010 3:07 am |
|
|
Thanks for the answer, Gary.
Unfortunately, this does not work. When I try calling write_program_eeprom(), CCS only returns with "Undefined identifier - write_program_eeprom". I couldn't find the topic on this function in the reference manual, although there are links to it in the manual (that don't work).
Is this function maybe called something else that is not documented? |
|
![](templates/subSilver/images/spacer.gif) |
Gary Smithson
Joined: 13 Feb 2004 Posts: 22
|
|
Posted: Thu Jun 03, 2010 10:52 am |
|
|
Welcome to the downside of using CCS compilers.
This is likely a CCS "bug" that needs reporting. The function should be available at compile time, it should work as advertised, it should be described in more detail in the manual, and the manual search features should lead the user to its documentation. Please report the problem to CCS. They do not act on forum posts as bug reports.
If you can convince them to respond quickly, that will be the fastest way to solve your problem. Other solutions such as writing the function yourself will require significant time.
Gary |
|
![](templates/subSilver/images/spacer.gif) |
miketwo
Joined: 04 Aug 2010 Posts: 24
|
|
Posted: Thu Sep 16, 2010 3:34 pm |
|
|
Resurrecting this topic after 4 years, cause I'm basically trying to do the same thing. (Bootloader at end of program memory, "goto bootloader" at beginning of memory.
Swys, did you end up solving your problem? |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 17, 2010 7:21 am |
|
|
Quote: | Resurrecting this topic after 4 years | Well, its not that old. Closer to 4 months.
Quote: | Swys, did you end up solving your problem? | The original poster had problems with the Write_program_eeprom() function not being in the manual. Well, it is in my June 2010 version.
Also, the original poster was using v4.107 of the compiler. Current version is 4.112. I don't have this release, but it might solve the original compiler error problem.
Miketwo,
What is your exact problem?
And which compiler version are you using?
Also read the additional information in the manual for the different program memory write functions. It is attached to the write_program_memory() function, easy to overlook as it is on the next page (282 of the June 2010 manual). |
|
![](templates/subSilver/images/spacer.gif) |
miketwo
Joined: 04 Aug 2010 Posts: 24
|
|
Posted: Fri Sep 17, 2010 10:19 am |
|
|
ckielstra wrote: | Well, its not that old. Closer to 4 months. |
Hah. Whoops. I think it was a long day for me.
Quote: | What is your exact problem?
And which compiler version are you using?
Also read ... |
Thank you, that was helpful. I read the manual shortly after posting, and realized that my problem was more architectural than procedural.
The problem is that I have a bootloader (based on CCS's examples) at the end of program memory, and I wanted to redirect the RESET vector to it, and allow it to decide whether to reprogram or just redirect to main().
The first problem I ran into was the same as Swys. Rewriting the first few instructions with write_program_memory () would erase all sorts of stuff I didn't want it to erase. As I went further down this path, I realized I don't really want to erase sector 0 at all. Because a reset halfway through reprogramming would basically brick my system.
I took a step back and posted a more philosophical question, to try to fix the overall architecture so I'm not trying to erase-and-then-restore-quickly the first sector in program memory.
The answers on that post have really helped a lot, and have led me to Microchip's AN1157, which I'm now working through. Any sage advice along these lines is definitely welcome. |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Sep 17, 2010 11:11 am |
|
|
Technically, PIC 18 has a erase block size of 64 bytes and program size of 16 bytes. To rewrite a flash memory block, it has to be erased before unless it was left unprogrammed since last erase action. You can't rewrite individual words of program flash. |
|
![](templates/subSilver/images/spacer.gif) |
|