Constants in pgmspace and bootloader

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I try to avoid moving a constant string from prmspace to SRAM. Therefore, the application uses pgmspace.h alot.

Now, I am building a bootloader, hoping to reuse much of the existing code. Since this bootloader code is above the above the 64K byte boundary, many pgmspace.h methods won't work because bit16 is lost from a word address.

I wonder if there is a way to modify pgmspace.h so that ALL of the constants were in the higher 64K (instead of the lower). ? ? ?

I don't understand the pgmspace.h file very well

thanks abunch ...Jim H.

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The functions that end in "_far" for accessing 32 bit addresses won't work for you ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

They might work ok, but the address will require more space. I'm stingy about the resources for an embedded device.

When the variable is in pgmspace, the nature of accessing it is different (besides the width of the address).
For example, str functions that access pgmspace strings are different functions than normal. e.g. strcpy_P(),etc.

thanks ...Jim H.

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I assume you are using avr-gcc - you should have started the thread in that forum.

My remarks on using the "high" program space for data are here, especially read the "segmented" stuff (which did not make into the "official" pgmspace.h in avr-libc v1.7/WinAVR20100110, but that is incorrectly compiled anyway for the _far functions, so
you are better off using it in an old fashioned "manual" way anyway).

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks JW, this looks like an excellent approach.

I my case, the problem is possibly simplified because all of the flash is in the high area (by definition because it is a bootloader). If I could find a solution that takes advantage of 'All High', it would be good.

thanks indiana, I may end up using "_far".

...Jim H.

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW - I am using a printf local to my project, so it can be easily made to conform to different segments.

...Jim H.

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What flash based data would a bootloader need anyway? The usual goal of a bootloader is to write it as "tight" as possible. Perhaps in a few hundred bytes. Not usually room for lots of const data.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Gosh Cliff,
I just wanted to signon to get started.
Maybe use printf() to do that.
Just trying to re-use the code base. I usually have a debug monitor.

extern const char __attribute__((__progmem__)) strPowerUp[];
    printf_pm(strPowerUp,REV_MAJOR,REV_MINOR);

:D ...Jim H.

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If it's one printf() then does it being located out to RAM actually matter? It's not like a bootloader is going to have a large RAM requirement (apart from maybe some kind of receive buffer).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, that is true.
I have a CRT module now. One for the application and another one (slighty different) for the bootloader. I was thinking about publishing all of this stuff to AvrFreaks. Do you think that would be appropriate? :?:
thanks for all you help ...Jim H. :D

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
What flash based data would a bootloader need anyway? The usual goal of a bootloader is to write it as "tight" as possible. Perhaps in a few hundred bytes. Not usually room for lots of const data.

Aside: In my bootloader I have two look-up tables to accelerate computing 16-bit CRCs (to check and sign each individual packet in accordance with a communication protocol with which both the application and bootloader coexist) and 32-bit CRCs (to sign the entire firmware image).

In one variant, it's actually two bootloaders in one -- first, it accepts firmware through a USART as usual. Second, it is responsible for maintaining a complete clone in an external serial Flash of the last successfully applied firmware image (signified by a correct CRC), so that it can be automatically retrieved in case a future USART upgrade is corrupted due to, for example, being interrupted mid-stream (signified by powering-up into an incorrect CRC).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a _ctype[] array that normally uses pgmspace (outside of cLib).

This bootloader will always be the first to run at a reset. No mater what's going on in the application area, you can do a new load. Even if the application if blank or broke or whatever. Some signal will tell the bootloader to run (instead of jumping to the application). I have a button (along side the reset button), that can be the signal, or the bootloader continues if a certain character sequence is received with-in a certain time after reset. As long as the bootloader's code is never modified, you will be able to re-load a new application. That's really nice.

Jim H.

Minimize Coupling - Maximize Cohesion

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This was a test solution, just to see if it would work. All of the bootloader program code is in the upper 64K. Looking at the bootloader.lss, there were only "lpm" instructions used through out and no evidence that RAMPZ was ever used.

I edited pgmspace.h changing all "lpm" to "elpm". Then edited the CRT-startup code to set RAMPZ to 1 instead of 0.

Everything seems to work ok. All program memory instructions are now "eplm" and "RAMPZ" is statically set to 1, so all of the program memory access is to pape 1 which is the location of the bootloader.

who would believe :lol: ...Jim H.

Minimize Coupling - Maximize Cohesion