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 support@ccsinfo.com

Write to 0x00 erases memory?

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



Joined: 24 Feb 2010
Posts: 22

View user's profile Send private message

Write to 0x00 erases memory?
PostPosted: Wed Jun 02, 2010 7:02 am     Reply with quote

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
Gary Smithson



Joined: 13 Feb 2004
Posts: 22

View user's profile Send private message Visit poster's website

PostPosted: Wed Jun 02, 2010 10:40 am     Reply with quote

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
Swys



Joined: 24 Feb 2010
Posts: 22

View user's profile Send private message

PostPosted: Thu Jun 03, 2010 3:07 am     Reply with quote

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?
Gary Smithson



Joined: 13 Feb 2004
Posts: 22

View user's profile Send private message Visit poster's website

PostPosted: Thu Jun 03, 2010 10:52 am     Reply with quote

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
miketwo



Joined: 04 Aug 2010
Posts: 24

View user's profile Send private message

PostPosted: Thu Sep 16, 2010 3:34 pm     Reply with quote

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?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 7:21 am     Reply with quote

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).
miketwo



Joined: 04 Aug 2010
Posts: 24

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 10:19 am     Reply with quote

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.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 11:11 am     Reply with quote

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.
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