Convert From IAR to Atmel Studio

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

Hi there,

 

I'm hoping to get some help in converting from IAR to Atmel Studio 7.0.

 

 I have already gone through some tutorials

http://www.atmel.com/webdoc/avrl... and

http://www.nongnu.org/avr-libc/u...

 

And have converting a numbmer of elements such as intrinsics and interrupts.....

However still have some thing that I need to modify.

 

 

1. EEPROM

 

The original code has the following line

 

__eeprom config_structure ee_config;            // EEPROM stored copy

 

This create a structure which was stored in the eeprom.

 

This __eeprom is not found in the avr gcc and I was wanting to find what I can exchanged it with.

 

Some research make me think I can use the following

 

#include <avr/eeprom.h>

EEMEM config_structure ee_config; 

 

Can someone please confirm that this is correct?

 

or perhaps 

config_structre ee_config __attribute__((section(".eeprom")))

?

 

2. FLASH

 

The current code I am working with has the following lines for the flash.

 

#pragma segment = "FLASHWRITE"

 

void avr_flash_wait(void) @ "FLASHWRITE"
{
  while(SPMCSR & 0x01)                        // flash operation must be complete
    ;
  while(EECR & 0x02)                          // EEPROM must be idle
    ;
}

 

I'm not too familiar with this terminology, and can't find references to it elsewhere, but I believe the idea is that this function (and other similar function) are designed to reside in the Read While Write section of the FLASH.

 

I notice the manual discusses the macro PROGMEM.

 

Can I just replace the @ "FLASHWRITE" with PROGMEM?

 

Any help would be much appreciated.

 

 

 

 

 

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

the_fiery_phoenix wrote:

#include <avr/eeprom.h>

EEMEM config_structure ee_config; 

 

Can someone please confirm that this is correct?

 

or perhaps 

config_structre ee_config __attribute__((section(".eeprom")))

?

Given that EEMEM is simply:

#define EEMEM __attribute((section(".eeprom")))

then those two things are the same and, yes, that is exactly the way to do it. Of course the real difference comes when you actually want to read/write the whole struct or members within it. In IAR I believe the EEPROM access code is implict, The very fact you used the __eeprom modifier means that when you do something like:

ee_config.some_member = 123;

then the compiler emits code to write to the EEPROM and similarly when you use:

RAMvar = ee_config.member;

it emits code to read from EEPROM. With GCC the access must be explicit so something like:

eeprom_update_word(&ee_config.some_member, 123);

RAMvar = eeprom_read_byte(&ee_config.member);

the_fiery_phoenix wrote:

2. FLASH

 

The current code I am working with has the following lines for the flash.

 

#pragma segment = "FLASHWRITE"

 

void avr_flash_wait(void) @ "FLASHWRITE"
{
  while(SPMCSR & 0x01)                        // flash operation must be complete
    ;
  while(EECR & 0x02)                          // EEPROM must be idle
    ;
}

 

I'm not too familiar with this terminology, and can't find references to it elsewhere, but I believe the idea is that this function (and other similar function) are designed to reside in the Read While Write section of the FLASH.

 

I notice the manual discusses the macro PROGMEM.

 

Can I just replace the @ "FLASHWRITE" with PROGMEM?

 

Any help would be much appreciated.

No you can't just use "PROGMEM" (or these days __flash) here because that is for READ-ONLY access to data in flash. If you have something like:

uint8_t data[] PROGMEM = { 1, 15, 26, 41 };

uint8_t RAMvar;

RAMvar = pgm_read_byte(&data[2]);

then the PROGMEM in that says "store data[] only in flash, do not copy to RAM". Then to access the data in flash a function like pgm_read_byte() bust be used to get the compiler to emit code using LPM opcodes (Load from Program Memory). The modern equivalent of that using __flash is:

const __flash uint8_t data[] = { 1, 15, 26, 41 };

uint8_t RAMvar;

RAMvar = data[2];

The compiler now "knows" that data[] is in flash and so the access to data[2] just implicitly uses an LPM. But all this is only for READ.

 

But none of this helps with you (2). In that you are talking about WRITING to flash at run time. To do that requires the SPM opcode to be used and most AVRs (mega) the SPM opcode can only execute from the "Bootloader Section" aka "BLS". So the job (a bit like "@ FLASHWRITE") is to get the code that will be using SPM to locate in high flash addresses. The way to do that is:

__attribute((section(".high_flash"))) void write_flash(parms) {
    // stuff
}

That says "put this function called write_flash in some memory section called .high_flash". Later on another command given during the linking phase will be:

-section-start=.high_flash=0x1234

which will arrange for anything that has been assigned to the high_flash section to be placed from byte address 0x1234 onwards. For the chip being used you look up where the BLS begins (it will vary according to the BOOTSZ fuses) and you ensure that the address (replacing 0x1234) given is within the BLS. It doesn't have to be called "high_flash" by the way. Pick any name you like. Some might use ".boot_section" or perhaps even ".bootloader" as SPM is usually being used for the implementation of a bootloader. But maybe you code is just writing flash as a data storage area?

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

Hi clawson,

 

Thanks for the response.

 

Just wanted to clarify some things.

 

 

1 EEPROM

 

Is there a difference between:

a. EEMEM config_structure ee_config; 

b. config_structure EEMEM ee_config; 

c. config_structure ee_config EEMEM; 

 

I'm not fully familiar with the attribute keyword yet, but does it have a specific location in the code syntax. And, if not, is there a preferred usage in standard code principles?

 

 

Next, if I want to convert the eeprom structre, ee_config, into a ram version, ram_config, can I use eeprom_read_block, or is it better to do it in parts?

 

 

2. Flash

 

I think I'm starting to understand this.

 

Where do I put this line?

 

-section-start=.high_flash=0x1234

 

Is this under the project properties? Under AVR/GNU Linker->Miscellaneous?

 

 

And just so I'm clear with this, the functions like 

boot_page_write

which is a SPM opcode, can only be run if stored in the bootloader section. And so setting the function attribute to ".high_flash" put the function in the bootloader section, and hence can run the SPM opcode function.

 

 

Next question, how does the compiler know that the attribute section is stored in flash/bootloader/program memory, and not sram/data memory space.

 

Is it the fact I have given it the "attribute section", which in itself means that section is somewhere in the program memory and not data memory?

Is it the label .high_flash/.bootloader that it know these terms, or are these just random labels?

Is it based on the address I give it in 

-section-start=.high_flash=0x1234

which is located in the program memory rather than the data memory?

 

 

 

In terms of flash memory storage, im looking at the BOOTSZ fuse.

It tells me Boot Flash size = 2048 words start address = $3800

 

Why is the start address not at $0000? 

As Program memory, data memory, and eeprom have their own memory maps, what would be taking up the initial address in the program memory?

Or this this put aside for storing the code?

 

 

I think I'm starting to get the picture, but hoping to just confirm my thoughts so I know im on the right track.

 

Thanks :)

 

 

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

1) No it doesn't matter where you place EEMEM (the __attribute__())

the_fiery_phoenix wrote:
ram_config, can I use eeprom_read_block, or is it better to do it in parts?
That's completely up to you and how much RAM you have available. A lot of people might read the complete "config" from EEPROM at power on, make local amendments in the RAM copy then from time to time eeprom_update_block() the whole thing back (difference between _write and _update is that the latter only actually writes the bytes that have changed so it should not "wear" the EEPROM if most fields don't change). Others might prefer to eeprom_read_byte(&ee_confing.some_member) and the same for updates to do individual members. In this case you only need as much RAM as the handful of members you are trying to read.

the_fiery_phoenix wrote:
Where do I put this line?
A -section-start is a directive to the linker so if you are using AS7 the project properties have entries for both Compiler and Linker. If nothing else you could put it in the "Miscellaneous" box for the linker. Because most code building is done by invoking "avr-gcc" (which is not the "compiler" but the "compiler driver") it has the ability to invoke compiler, linker and assembler. For unique options it knows which one to pass them to but if there's any possibility that more than one of the tools have similar options you can specifically add "-Wl," to the front of anything for the linker and "-Wa," to the front of anything specifically for the assembler so in this case you might use "-Wl,-section-start=.wherever=0x1234" to be clear that it goes to the linker. 

 

Now, having said all that, if it is AS7 then Atmel have added a section in the properties called "Memories" and in that you can just enter ".wherever=0x1234" in the group for "Flash memory" and it will pass a -Wl,-section-start... for you. HOWEVER note that Atmel are an odd bunch and while the whole world and his wife almost always address all memory in terms of bytes addresses, Atmel in their wisdom choose, for flash alone (but not RAM or EEPROM) to use word addressing. So when you give an address for a flash section to them they expect it to be a word address and then they do a "hidden" times-2 on it when they form the -section-start so to get the equivalent of 0x1234 for a section in flash you would actually enter ".wherever=0x91A" (where 0x1234 / 2 = 0x91A). I find that all so confusing I just enter manually typed -section-start's myself.

the_fiery_phoenix wrote:
which is a SPM opcode, can only be run if stored in the bootloader section. And so setting the function attribute to ".high_flash" put the function in the bootloader section, and hence can run the SPM opcode function.
Yeah, you got it. Anything that is going to try and do SPM has to be located in the high section. Note that when SPM operates the majority of the flash in the AVR becomes "invisible" and just returns 0xFF when read. So if the SPM code is accompanied by other functions that are pulling in data and organising the high level parts of the write then maybe you want them to remain visible during the entire (page wise) writing operation. So you would assign all the functions to the high section so they are all "up high". Something like:

#define IN_BLS __attribute__((section(".flash_write")))

IN BLS void foo(void) {
    // stuff
}

IN BLS void bar(void) {
    // more stuff
}

IN BLS void do_spm(void) {
    // SPM stuff
}

IN BLS void flash_write_coordinator(void) {
    foo();
    bar();
    do_spm();
}

Any function you add "IN_BLS" to will be located in ".flash_write" and then you finish with -Wl,-section-start=.flash_write=0x2468

the_fiery_phoenix wrote:
Next question, how does the compiler know that the attribute section is stored in flash/bootloader/program memory, and not sram/data memory space.

It doesn't! There is a convention in GCC that:

MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = 128K
  data   (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
  signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
}

So anything in flash is placed in 0x000000..0x7FFFFF then anything in (max 64K) RAM is 0x800000 to 0x80FFFF, anything in (max 64K) EEPROM is 0x810000..0x81FFFF and so on.

 

So it really comes down to the number you set in the -section-start. However there is also the question of how the flash load image (and the eeprom load image) are later created by objcopy. For flash there is a command like:

Either

avr-obcopy -O ihex -R .eeprom -R .fuse -R .lock proj.elf proj.hex

Or

avr-obcopy -O ihex -j .text -j .data -j .flash_write proj.elf proj.hex

If -R's are used then anything that is not -R(emoved) will go into the final .hex so if you have .flash_write then along with .text and .data it will go into the flash image. If, on the other hand the build system chooses to use -j's then all sections that are needed in the output have to be listed as -j's so in this case if .flash_write is to be part of the .hex for the flash it has to be listed as a -j. I think AS7 uses the -R method in fact. The .eep file for programming EEPROM (which is really Intel Hex too) is created by something more like:

avr-obcopy -O ihex -j .eeprom -make_addr_adjustment 0x810000 is_rebased_to 0x0000 proj.elf proj.eep

The actual syntax actually involves LMAs and VMA (Virtual Memory Address) and other quaint stuff but what it's really doing is bringing the section that has been built at 0x810000 back down to the 0x0000 address at the start of the EEPROM.

the_fiery_phoenix wrote:
Is it the fact I have given it the "attribute section", which in itself means that section is somewhere in the program memory and not data memory?

You can use this -section-start thing for locating both code AND data and for the data you may move it to some other RAM location. This is the thing about Harvard CPUs, there are multiple address=0's, flash has one, RAM has one, EEPROM has one (even .lock and .fuse have one!). GCC is a Von Neumann compiler and does not know about multiple memory spaces so one big linear address space is split so that different regions in it have different target uses. The linker maintains location pointers in each.

the_fiery_phoenix wrote:
Is it the label .high_flash/.bootloader that it know these terms, or are these just random labels?
Random labels. This time I chose .flash_write. I would pick names that try to say what the usage is. So if you are writing a true bootloader I would be tempted to use ".bootloader" but if these are just some data storage routines to be added to some app then I would go with ".my_spm_routines" or ".flash_write" or ".located_up_high" or ".in_the_BLS" or some term that describes to you and the future code maintainer what the function is.

the_fiery_phoenix wrote:
In terms of flash memory storage, im looking at the BOOTSZ fuse. It tells me Boot Flash size = 2048 words start address = $3800
Be very careful here. This is where the Atmel madness shows its face again (and why that "Memories" dialog in AS7 is so confusing). I am guessing you are talking about a 32K chip here (not a 328 by any chance?). Now you and I would say that 32K is 0x0000 to 0x7FFF. Every programmer on Earth knows that 0x8000 is "32K" right? Well not Atmel. Because the granularity in the flash space is 16 bit (minimum opcode size and even minimum alignment for making an LPM access) they use words. So a "2048 word" bootloader is 4K bytes. 4K bytes off 32K is 28K. 28K for most programmers is 0x7000 but Atmel will tell you this is 0x3800 (which is 0x7000 / 2). So if you use GCC (which always uses "bytes" for all memory addressing) then you actually want to use -Wl,-section-start=.some_place=0x7000 but if you use "Memories" in the AS7 project settings you would enter ".some_place=0x3800" and Atmel "do you a favour" by taking the number you entered and doubling it when they finally create the -section-start.

the_fiery_phoenix wrote:
Why is the start address not at $0000? 
Read the "Memory" chapter in your AVr datasheet. If it is a 32K micro then at power on it fetches the first opcode from 0x0000 and you have 32K for your program. HOWEVER if you choose to split the program into app code at 0x0000 and flash writing routines at 0x3800/0x7000 then when you come to flash write you call up to somewhere at or above 0x7000 (I'm sticking with bytes!) and that does SPM and while the erase and writes are occuring the flash block from 0K to 28K "disappears" and just the 4K at the top remain operational for opcode fetches. In a true bootloader what actually happens is that not only do you stick with BOOTSZ setting the split point at 28K or 30K or 31K or 31.5K but you also enable the BOOTRST fuse. Now when power is appllied to the AVR it fetches the first opcode not from 0x0000 but from 28K or 30K or 31K or 31.5K and that "bootloader" runs first and decides if it wants to do some flash writing or, if not, it ends by jumping down to 0x0000 to run the "app" that it knows is already in place at that address.
the_fiery_phoenix wrote:
As Program memory, data memory, and eeprom have their own memory maps, what would be taking up the initial address in the program memory? Or this this put aside for storing the code?
Not sure I understand what you are asking but hopefully I already answered it?

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

clawson wrote:
Not sure I understand what you are asking but hopefully I already answered it?
 

You probably have answered it.

 

I read the question as if the OP assumed the bootloader would be at start of flash.

 

I'll just flesh out..

 

So, to make the basic fact clear to the_fiery_phoenix: The bootloader is placed at the end of flash memory. See clawsons remarks above, and the memory chapter in the data sheet that he refers to!

 

I've always assumed the reason for placing the bootloader at the end is because then you always build the main application with starting address zero. This makes that build process "immune" of whether there is a bootloader in place in the target system or not.

 

Had it been the other way around, you'd need to build the main app with the knowledge not only if the target system has a bootloader or not, but also how big the bootloader is. You'd need a different build for each case of existing (and size of) bootloader.

 

That in itself would be quite akward, but also the very nature of a bootloader is that it will be built and programmed to flash more or less one time, but the main application will potentially be built and programmed to flash many times.

 

It makes a lot of sense to have the bootloader at the end of flash leaving the start of flash for the main application.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Thanks guys for all the explanation.  I think that clears up my questions and understanding of the system.  Though the Atmel words vs bytes seems more confusing than it should be.

I should have enough to complete what I need to, but I have some other question just to confirm my understanding.

 

Not sure I understand what you are asking but hopefully I already answered it?

I think my initial thought was that the "start address = $3800" was the start of the flash (probably cos I though it was in bytes), not the bootloader.  So I was confused as to what sat in those $3800 bytes. So in my mind there was this blank section of memory that held nothing.... :/

 

 

 

 

This comment seems to conflict with what the original code did in IAR

Read the "Memory" chapter in your AVr datasheet. If it is a 32K micro then at power on it fetches the first opcode from 0x0000 and you have 32K for your program. HOWEVER if you choose to split the program into app code at 0x0000 and flash writing routines at 0x3800/0x7000 then when you come to flash write you call up to somewhere at or above 0x7000 (I'm sticking with bytes!) and that does SPM and while the erase and writes are occuring the flash block from 0K to 28K "disappears" and just the 4K at the top remain operational for opcode fetches. In a true bootloader what actually happens is that not only do you stick with BOOTSZ setting the split point at 28K or 30K or 31K or 31.5K but you also enable the BOOTRST fuse. Now when power is appllied to the AVR it fetches the first opcode not from 0x0000 but from 28K or 30K or 31K or 31.5K and that "bootloader"

runs first and decides if it wants to do some flash writing or, if not, it ends by jumping down to 0x0000 to run the "app" that it knows is already in place at that address.

And the .map file give me the following.

Absolute parts
           ENTRY                   ADDRESS         REF BY
           =====                   =======         ======
           _..X_FLASHWRITE_START   00007000 
           _..X_NEAR_HEAP_SIZE     00000080 
           _..X_HEAP_SIZE          00000080 
           _..X_RSTACK_SIZE        00000040 
           _..X_CSTACK_SIZE        00000100 
           _..X_EEPROM_END         000003FF 
           _..X_SRAM_END           000008FF 
           _..X_SRAM_TEND          00000100 
           _..X_SRAM_BASE          00000100 
           _..X_FLASH_END          00007FFF 
           _..X_FLASH_NEND         00007FFF 
           _..X_FLASH_TEND         000000FF 
           _..X_INTVEC_SIZE        0000007C 

 

This shows that the "FLASHWRITE" is at 0x7000 of the FLASH memory. (These are absolute, not relative memory locations)

 

This is confirmed later in the .map file

 

SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
INTVEC               CODE          00000000 - 00000073          74   com    1
?FILL1               CODE          00000074 - 0000007B           8   rel    0
NEAR_F               CODE          0000007C - 00000477         3FC   rel    0
SWITCH               CODE               00000478                     dse    0
INITTAB              CODE          00000478 - 00000483           C   rel    0
CODE                 CODE          00000484 - 000036EF        326C   rel    1
TINY_ID              CODE               000036F0                     dse    0
NEAR_ID              CODE          000036F0 - 0000381B         12C   rel    0
FLASHWRITE           CODE          00007000 - 00007191         192   rel    1
ABSOLUTE             DATA               0000001F                     rel    0
                     DATA               00000020                   
                     DATA          00000024 - 00000025           2 
                     DATA          00000027 - 00000028           2 
                     DATA          0000002A - 0000002B           2 
                     DATA          0000003D - 0000003D           1 
                     DATA          0000003F - 0000003F           1 
                     DATA          00000044 - 00000045           2 
                     DATA          00000047 - 00000047           1 
                     DATA          00000053 - 00000054           2 
                     DATA          00000057 - 00000057           1 
                     DATA          00000060 - 00000060           1 
                     DATA          00000064 - 00000064           1 
                     DATA          00000068 - 00000069           2 
                     DATA          0000006B - 00000070           6 
                     DATA          000000C0 - 000000C2           3 
                     DATA          000000C4 - 000000C6           3 
                     DATA          000000C8 - 000000CA           3 
                     DATA          000000CC - 000000CE           3 
NEAR_I               DATA          00000100 - 0000022B         12C   rel    0
NEAR_Z               DATA          0000022C - 000004BE         293   rel    0
RSTACK               DATA          000004BF - 000004FE          40   dse    0
CSTACK               DATA          000004FF - 000005FE         100   dse    0
EEPROM_I             XDATA         00000000 - 0000000E           F   rel    0

 

However, the code in the 'FLASHWRITE' section pulls data from the flash, which has been allocated to start at either address 0x5000 (strings) or 0x6000 (codes)

 

But, you wrote

 flash writing routines at 0x3800/0x7000 then when you come to flash write you call up to somewhere at or above 0x7000 (I'm sticking with bytes!) and that does SPM and while the erase and writes are occuring the flash block from 0K to 28K "disappears" and just the 4K at the top remain operational for opcode fetches. 

My interpretation of your comment is that the SPM should only access data above 0x7000, yet it is getting data from a lower address, at 0x6000/0x5000. 

 

What am I not understanding here?

 

Note: .map file is from the IAR compiler as I havent finished moving across yet

Also, the chip is an ATmega324p.

 

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

Also, quick note.  I tried the section for flashwrite

 

 

-Wl,-section-start=.FLASHWRITE=0x7000

 

This is relfected in the .map file here.

 

.FLASHWRITE     0x0000398e      0x1f2
 .FLASHWRITE    0x0000398e      0x1f2 avr_flash.o
                0x0000398e                avr_flash_wait
                0x0000399a                avr_flash_restore_rww
                0x000039ac                avr_flash_page_erase
                0x000039cc                avr_flash_page_write
                0x00003a5c                avr_flash_get
                0x00003a88                avr_flash_update_page
                0x00003af2                avr_flash_put

 

Why does the map file put it at 0x398e, instead of 0x7000.

I'd guess this is to do with word and byte? But want to confirm because I put the section attribute in the miscellaneous section.

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

And people tell me that writing assembler is unnecessarily complicated.  ;-)  S.

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

the_fiery_phoenix wrote:

Also, quick note.  I tried the section for flashwrite

 

 

-Wl,-section-start=.FLASHWRITE=0x7000

 

This is relfected in the .map file here.

 

.FLASHWRITE     0x0000398e      0x1f2
 .FLASHWRITE    0x0000398e      0x1f2 avr_flash.o
                0x0000398e                avr_flash_wait
                0x0000399a                avr_flash_restore_rww
                0x000039ac                avr_flash_page_erase
                0x000039cc                avr_flash_page_write
                0x00003a5c                avr_flash_get
                0x00003a88                avr_flash_update_page
                0x00003af2                avr_flash_put

 

Why does the map file put it at 0x398e, instead of 0x7000.

I'd guess this is to do with word and byte? But want to confirm because I put the section attribute in the miscellaneous section.

not enough detail/context.

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

Hey Clawson,

 

There were two running comments, which it appear you missed the first one.

 

The first one discusses your implication that the SPM can only read/write flash address greater than 0x7000, yet the code I'm using it meant to store data at address 0x5000 and 0x6000.

 

The second question was to say, I inputted that line into the miscellaneous section, but it appeared to put it at address 0x398e.

I recently changed the line and halved it, and put it in the Memory Settings.  This seems to have put it at 0x7000, which is where I think it was meant to go.

 

 

I now have an odd issue.  I have a work around, but I dont like it for long term use.

 

I appear, with optimization turned off, my code is too large, in that some of the code sit in the memory location 0x5000+.  This is a problem because this is where I was storing my strings, hence the string overwritting the code which causes problems.

However, if I turn optimization on, i can essentially half the code size.  However, when I do this, the flash write does not work at all.

 

I have solve it by moving the strings to memory location 0x7500+, as they fit.  But I would like to know why optimization makes working code suddenly not work.

 

 

 

 

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

On a phone so brief answer but SPM is only limited in that it can only execute in the BLS but there's no limit to the flash range it can WRITE to. It will happily write to 0x5000/60000.
.
As for your stuff at 389E, clearly you are doing some part of it wrong. Without seeing EVERYTHING I can't say what. Hence my previous comment about not enough context.
.
As for optimization preventing flash write. Again you are clearly doing something wrong but it would require everything to diagnose that too.

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

It seems that the optimization is preventing the read not working.

 

However, I have moved the address mapping around so the data fit.

Also, I am using pragmas to optimise specific sections which has reduce it as well.

 

Thanks for the help :)