97 posts / 0 new

Pages

Author
Message

HI all,

This is my first question in the form. I will try my best to follow the rules and be as clear as possible

I am working with Atmega32u4 (in Arduino board-this is BASED OF THE CATERINA BOOTLOADER) and I'm trying to write data to flash memory from the application. After a lot of research and long working hours I came close but not there yet.

I Defined a function called Do_spm_N () that write data to flash memory, in the bootloader section. Mad sure that the section lives in the bootloader part.

in my application I'm calling the function to write data to flash. however nothing written to flash. memory any idea what could be wrong. here is the code

1- defining function in the bootloader

// this part in my bootloader.c

:
:
:
:
...
:
:
:
:
......
static void do_spm_N (uint32_t address,  uint8_t *data){

uint16_t i;
uint8_t sreg;
// Disable interrupts.
sreg = SREG;
cli();
eeprom_busy_wait ();
boot_spm_busy_wait ();      // Wait until the memory is erased.
for (i=0; i<SPM_PAGESIZE; i+=2)
{
// Set up little-endian word.
uint16_t w = *data++;
w += (*data++) << 8;

}
boot_page_write (address);     // Store buffer in flash page.
boot_spm_busy_wait();       // Wait until the memory is written.
// Reenable RWW-section again. We need this if we want to jump back
boot_rww_enable ();
// Re-enable interrupts (if they were ever enabled).
SREG = sreg;
// this is for indication
for(int i=0; i >= 5;i++){
L_LED_ON();
delay(10);

RX_LED_OFF();
TX_LED_OFF();
L_LED_OFF();
delay(10);
RX_LED_ON();
TX_LED_ON();
L_LED_ON();
delay(10);
RX_LED_OFF();
TX_LED_OFF();
L_LED_OFF();
}

}

// MAKE FILE
LDFLAGS += -Wl,--section-start=.bootloader=(BOOT_START)  3- defining the function and calling it in my application // APPLication.h static void (*do_spm_N)(uint32_t address, uint8_t *data)__attribute__ ((section(".bootloader"))) ; // Application.ino (the atmerga32u4 lives in an arduino board) const char flash_buffer[SPM_PAGESIZE] __attribute__ (( aligned(SPM_PAGESIZE) )) PROGMEM= {}; char Str [] = " 0123456789ABCDEFGHIJKLMNOPQRSTUVW"; uint8_t ram_buffer[SPM_PAGESIZE]; void setup() { // Init serial Serial.begin(9600); for (int i = 0; i<= sizeof(Str);i++){ ram_buffer[i] =Str[i]; } } void loop() { // no code here int i; uint8_t c; uint16_t w; byte data ino // Print current flash buffer content if (Serial.available() > 0 ) { data = Serial.read() ; switch (data) { case 'w':{ do_spm_N ((uint32_t) &flash_buffer[0], *ram_buffer); } } } } Any idea/suggestion ? thanks in advance Supporting Information:- Last Edited: Thu. Oct 11, 2018 - 03:34 PM Total votes: 0 What does the hex or nm say? Total votes: 0 An AVR's idea of the bootloader section depends on its fuses. The linker's idea of the .bootloader section depends on(BOOT_START).

Do they match?

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

WHY are you writing to flash memory from a running application?   This is never done.

If you need to store lots of data, even through power cycles, use serial EEPROM or FRAM.  Here is an example of a simple 512 x 8 8-pin cheap EEPROM IC.  Other serial EEPROMs hold up to 128K bytes in the same pin-out:

https://www.ebay.com/itm/25LC040...

Last Edited: Fri. Oct 5, 2018 - 02:23 AM

This is never done.

Rubbish.

It is infrequently done, but 'never' is a long time.

 "Experience is what enables you to recognise a mistake the second time you make it." "Good judgement comes from experience.  Experience comes from bad judgement." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "When you hear hoofbeats, think horses, not unicorns." "Fast.  Cheap.  Good.  Pick two." "We see a lot of arses on handlebars around here." - [J Ekdahl]

Simonetta wrote:
This is never done.
As someone who has done exactly this - written to flash in an app - this just proves what utter nonsense you talk almost all the time. You clearly have no idea how micros are used at all so I don't know who you think you can advise people about the subject with such utter drivel and misinformation?

I think the .hex file is correct ( I might be wrong). I looked at the hex and it starts at the correct address (per my calculation )

here is the first 20 lines

:1070000074C000008DC000008BC0000089C000006B
:1070100087C0000085C0000083C0000081C0000060
:107020007FC000007DC0000007C5000079C00000DF
:1070300077C0000075C0000073C0000071C0000080
:107040006FC00000FEC000006BC0000069C00000FF
:1070500067C0000065C0000063C0000061C00000A0
:107060005FC000005DC000005BC0000059C00000B0
:1070700057C0000055C0000053C0000051C00000C0
:107080004FC000004DC000004BC0000049C00000D0
:1070900047C0000045C0000043C0000041C00000E0
:1070A0003FC000003DC000003BC00000873EA03E46
:1070B0004C3FA03E4C3FD83EFA3E4C3F1A3F2C3F3F
:1070C0002203300030003000320034003900340038
:1070D00033003500380000001201100102000008E2
:1070F000DAE0DEBFCDBF11E0A0E0B1E0E2E2FFE701
:1071000002C005900D92AE39B107D9F721E0AEE982
:10711000B1E001C01D92A73FB207E1F762D3FFC6FD
:107120006FCF84E08093E9008091E80085FD0DC079
:107130008091E8008B778093E8008091E80082FDE1

But what is "nm"?

Last Edited: Fri. Oct 5, 2018 - 12:36 PM

clawson wrote:

What does the hex or nm say?

I think the .hex file is correct ( I might be wrong). I looked at the hex and it starts at the correct address (per my calculation )

here is the first 20 lines

:1070000074C000008DC000008BC0000089C000006B
:1070100087C0000085C0000083C0000081C0000060
:107020007FC000007DC0000007C5000079C00000DF
:1070300077C0000075C0000073C0000071C0000080
:107040006FC00000FEC000006BC0000069C00000FF
:1070500067C0000065C0000063C0000061C00000A0
:107060005FC000005DC000005BC0000059C00000B0
:1070700057C0000055C0000053C0000051C00000C0
:107080004FC000004DC000004BC0000049C00000D0
:1070900047C0000045C0000043C0000041C00000E0
:1070A0003FC000003DC000003BC00000873EA03E46
:1070B0004C3FA03E4C3FD83EFA3E4C3F1A3F2C3F3F
:1070C0002203300030003000320034003900340038
:1070D00033003500380000001201100102000008E2
:1070F000DAE0DEBFCDBF11E0A0E0B1E0E2E2FFE701
:1071000002C005900D92AE39B107D9F721E0AEE982
:10711000B1E001C01D92A73FB207E1F762D3FFC6FD
:107120006FCF84E08093E9008091E80085FD0DC079
:107130008091E8008B778093E8008091E80082FDE1

But what is "nm"?

Simonetta wrote:

WHY are you writing to flash memory from a running application?   This is never done.

NO< Let me correct you. I searched the web and It was done before for sure.

the EEPROm is small i need to use the rest of my flash memory to save data

clawson wrote:

Simonetta wrote:
This is never done.
As someone who has done exactly this - written to flash in an app - t

agree with you it was done before

skeeve wrote:

An AVR's idea of the bootloader section depends on its fuses.

The linker's idea of the .bootloader section depends on $(BOOT_START). Do they match? I 'm not sure how to check the fuses, any hint ? I am using a make file to compile . DO you mean BOOTSZ? Last Edited: Fri. Oct 5, 2018 - 12:50 PM Total votes: 0 avr-nm is one of the tools that comes with avr-gcc. If you happen to use AS7 then on the tools menu there is an entry for "Command Prompt". When you select that then PATH is set so all the avr-gcc tools like avr-gcc, avr-objcopy, avr-objdump, avr-ar, avr-nm can be found. It's basically these: C:\>where avr-gcc C:\program files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe C:\>cd C:\program files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin>dir avr-*.exe Volume in drive C is OSDISK Volume Serial Number is 7AF3-B2D0 Directory of C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin 13/09/2017 00:24 494,080 avr-addr2line.exe 13/09/2017 00:24 514,560 avr-ar.exe 13/09/2017 00:24 666,112 avr-as.exe 13/09/2017 00:24 736,768 avr-c++.exe 13/09/2017 00:24 492,544 avr-c++filt.exe 13/09/2017 00:24 735,744 avr-cpp.exe 13/09/2017 00:24 31,744 avr-elfedit.exe 13/09/2017 00:24 736,768 avr-g++.exe 13/09/2017 00:24 734,208 avr-gcc-5.4.0.exe 13/09/2017 00:24 49,664 avr-gcc-ar.exe 13/09/2017 00:24 49,152 avr-gcc-nm.exe 13/09/2017 00:24 49,152 avr-gcc-ranlib.exe 13/09/2017 00:24 734,208 avr-gcc.exe 13/09/2017 00:24 380,928 avr-gcov-tool.exe 13/09/2017 00:24 390,656 avr-gcov.exe 13/09/2017 00:24 3,988,480 avr-gdb-py.exe 13/09/2017 00:24 3,831,296 avr-gdb.exe 13/09/2017 00:24 544,256 avr-gprof.exe 13/09/2017 00:24 942,080 avr-ld.bfd.exe 13/09/2017 00:24 942,080 avr-ld.exe 13/09/2017 00:24 502,272 avr-nm.exe 13/09/2017 00:24 629,760 avr-objcopy.exe 13/09/2017 00:24 730,112 avr-objdump.exe 13/09/2017 00:24 514,560 avr-ranlib.exe 13/09/2017 00:24 393,728 avr-readelf.exe 13/09/2017 00:24 502,272 avr-size.exe 13/09/2017 00:24 495,104 avr-strings.exe 13/09/2017 00:24 629,760 avr-strip.exe 28 File(s) 21,442,048 bytes So if I now switch to a directory where a program has been built and give the command: C:\Users\uid23021\Documents\Atmel Studio\7.0\test1\test1\Debug>avr-nm test1.elf 00000076 T __bad_interrupt 00000062 T __ctors_end 00000062 T __ctors_start 00000096 A __data_load_end 00000096 A __data_load_start 0000ffa0 A __DATA_REGION_LENGTH__ 00000062 T __dtors_end 00000062 T __dtors_start 00810000 D __eeprom_end 00010000 A __EEPROM_REGION_LENGTH__ 00000002 A __FUSE_REGION_LENGTH__ 00000000 W __heap_end 00000062 W __init 00000400 A __LOCK_REGION_LENGTH__ 00000400 A __SIGNATURE_REGION_LENGTH__ 0000003e a __SP_H__ 0000003d a __SP_L__ 0000003f a __SREG__ 0000045f W __stack 00000094 t __stop_program 00020000 A __TEXT_REGION_LENGTH__ 00000000 a __tmp_reg__ 00000054 T __trampolines_end 00000054 T __trampolines_start 00000400 A __USER_SIGNATURE_REGION_LENGTH__ 00000076 W __vector_1 00000076 W __vector_10 00000076 W __vector_11 00000076 W __vector_12 00000076 W __vector_13 00000076 W __vector_14 00000076 W __vector_15 00000076 W __vector_16 00000076 W __vector_17 00000076 W __vector_18 00000076 W __vector_19 00000076 W __vector_2 00000076 W __vector_20 00000076 W __vector_3 00000076 W __vector_4 00000076 W __vector_5 00000076 W __vector_6 00000076 W __vector_7 00000076 W __vector_8 00000076 W __vector_9 00000000 W __vector_default 00000000 T __vectors 00000001 a __zero_reg__ 00800060 D _edata 00800060 D _end 00000096 T _etext 00000092 T _exit 00000092 W exit 00000054 T foo 0000007a T main  All of the code addresses in this are down near location 0. For a bootloader I'd expect these to be up near the BLS address. In fact "__vectors" should have the entry address. In this case that is 00000000. But anyway your .hex file already confirms the location: :1070000074C000008DC000008BC0000089C000006B It's the 7000 in that, just after the start of the line that gives the address as 0x7000 which is about right for the bootloader location in a 32K micro. (it'a actually 28K so it's 4K from the end of the chip). Total votes: 0 clawson wrote: your .hex file already confirms the location: :1070000074C000008DC000008BC0000089C000006B It's the 7000 in that, just after the start of the line that gives the address as 0x7000 which is about right for the bootloader location in a 32K micro. (it'a actually 28K so it's 4K from the end of the chip). OH I see. That will come handy one day. thanks for explanation. Yes the .hex confirm the bot location , but what could i be missing. DO you think I need to set lock bits i'm thinking to use something like that boot_lock_bits_set (_BV (BLB11)); what you think Total votes: 0 AVATAR_Freaks wrote: OH I see. That will come handy one day. thanks for explanation. The full explanation (as for so many things in like) is on Wikipedia: https://en.wikipedia.org/wiki/In... So: :1070000074C000008DC000008BC0000089C000006B should be read as: :10 7000 00 74C000008DC000008BC0000089C00000 6B length addr type data checksum  As to your problems. Just never go anywhere near lockbits until you are finally ready to deploy the product and they won't trouble you - so as long as there's been a chip erase and reprogram (which resets everything to default) forget the lockbits as an issue - they won't affect this. Total votes: 0 I am confused about your general setup. #define BOOTLOADER_SECTION __attribute__ ((section(".bootloader"))) ; ... static void do_spm_N (uint32_t address, uint8_t *data) BOOTLOADER_SECTION; LDFLAGS += -Wl,--section-start=.bootloader=$(BOOT_START)

So the function is part of a normal application (located at 0x0000) where only the function is relocated to the boot sector?

static void (*do_spm_N)(uint32_t address,  uint8_t *data)__attribute__ ((section(".bootloader"))) ;


But then why are you using a function pointer to call the function?

How is it possible that the pointer can have the same name as the function itself?

Where is this pointer even initialized?

What sense does it make to put the pointer into the .bootloader section?

And even more confusing, you have now presented a HEX file which contains a whole application (with interrupt vectors and all) being located in the boot sector.

Stefan Ernst

When I've done this in the past I have used the fact that <avr/boot.h> already has a definition of a BOOTLOADER_SECTION macro to assign a section attribute.

/** \ingroup avr_boot

Used to declare a function or variable to be placed into a
new section called .bootloader. This section and its contents



Then I just wrote the rest of the code like "normal C" just applying that macro to the handful of functions that needed to remain visible while SPM was operating (the rest of the code just switches to all 0xFFFF opcodes). No special consideration was needed for making the calls from the app functions to the SPM functions. Just code it like normal C but keep in mind that fact about "things disappearing" so relocate all the functions that might be required while SPM executes. And that, basically, is all there is to it. (not forgetting to do the -section-start thing on ".bootloader" to place it at/above the BLS address

:10     7000  00    74C000008DC000008BC0000089C00000 6B



is there a way to understand what "74C000008DC000008BC0000089C00000" actually means ?

ALso, If I erase and upload the bootloader , and the lockbits not set then i wont be able  to use SPM right ?

sternst wrote:

static void (*do_spm_N)(uint32_t address,  uint8_t *data)__attribute__ ((section(".bootloader"))) ;



The function called do_spm_N() lives in the bootloader sector which is located at address 0x7000 which is the start of the bootloader.

this is how i define it in my application which could be wrong:-

static void (*do_spm_N)(uint32_t address,  uint8_t *data)__attribute__ ((section(".bootloader"))) ; --> in application


[

sternst wrote:

But then why are you using a function pointer to call the function?

I though this is the way i should call it from my application, how else can I called from the application? i tried to use "extern" but it didn't compile any suggestions ?

[

sternst wrote:

How is it possible that the pointer can have the same name as the function itself?

Where is this pointer even initialized?

SO how can I point to an external function that is not defined in my sketch ?

[

sternst wrote:

What sense does it make to put the pointer into the .bootloader section?

NO the pointer is in the sketch

[

sternst wrote:

And even more confusing, you have now presented a HEX file which contains a whole application (with interrupt vectors and all) being located in the boot sector.

Yes it is a full application, but I only put the relevant parts :)

clawson wrote:

When I've done this in the past I have used the fact that <avr/boot.h> already has a definition of a BOOTLOADER_SECTION macro to assign a section attribute.

/** \ingroup avr_boot



this is basically what I'm doing.

clawson wrote:

Then I just wrote the rest of the code like "normal C" just applying that macro to the handful of functions that needed to remain visible while SPM was operating (the rest of the code just switches to all 0xFFFF opcodes). No special consideration was needed for making the calls from the app functions to the SPM functions. Just code it like normal C but keep in mind that fact about "things disappearing" so relocate all the functions that might be required while SPM executes. And that, basically, is all there is to it. (not forgetting to do the -section-start thing on ".bootloader" to place it at/above the BLS address

I feel like i taken care of all of that as you see previously, but i think maybe the way I call the function from my application

SO when I upload my bootloader to the baord and run an application both RX& TX LEDs are on as a sold color (not flashing), like it gets stuck.

Only if there is a ways  to debug, when the application call Do_SPM_N , does the bootloader  goes to that function or no?

So actually you have a bootloader and the function do_spm_N is part of it?

Then all this is nonsense:

#define BOOTLOADER_SECTION __attribute__ ((section(".bootloader"))) ;
...
static void do_spm_N (uint32_t address,  uint8_t *data) BOOTLOADER_SECTION;
LDFLAGS += -Wl,--section-start=.bootloader=$(BOOT_START) static void (*do_spm_N)(uint32_t address, uint8_t *data)__attribute__ ((section(".bootloader"))) ;  All you need in the application is a correctly initialized function pointer: void (*do_spm_N)(uint32_t address, uint8_t *data) = 0xXXXX; Replace 0xXXXX with the word address of do_spm_N within the bootloader. Stefan Ernst Total votes: 0 I wrote some words the other day (which turned out at the time to be misguided) about sharing bootloader functions to an application: https://www.avrfreaks.net/commen... You may find something of use there. The basic principle here is that the only piece of "shared knowledge" between the app code and the boot code is a 16 bit pointer passed from one to the other and also that each knows the order of entries in an array of function pointers (who's base address is passed as that 16 bit value). The actual routines in the boot code that are shared to the app can actually live anywhere in the bootloader space. Total votes: 0 clawson wrote: Simonetta wrote: This is never done. As someone who has done exactly this - written to flash in an app ... joeymorin wrote: It is infrequently done, but 'never' is a long time. Agree with "perhaps unusual but not unheard of". I suppose one needs to put aside for the moment the merit of it? I well might determine in an app that it might be easier/more cost efficient/smaller footprint to e.g. get a bigger model of the AVR family versus adding e.g. external flash or EEPROM or similar storage chip. Atmel chose to put out an app note many years ago, with a sample application: Butterfly Logger: https://www.brokentoaster.com/bu... Doesn't ButtLoad store the ISP image into flash? Arduino discussions: (many) https://forum.arduino.cc/index.p... https://arduino.stackexchange.co... Prior discussions here: (many) https://www.avrfreaks.net/forum/... https://community.atmel.com/foru... https://www.avrfreaks.net/forum/... You can put lipstick on a pig, but it is still a pig. I've never met a pig I didn't like, as long as you have some salt and pepper. Total votes: 0 AVATAR_Freaks wrote: skeeve wrote: An AVR's idea of the bootloader section depends on its fuses. The linker's idea of the .bootloader section depends on$(BOOT_START). Do they match? I 'm not sure how to check the fuses, any hint ? I am using a make file to compile . DO you mean BOOTSZ?
Yes.  Your IDE probably has a section for it somewhere.

If no IDE, avrdude can read them if you are not stuck with the wrong USB drivers.

The default bootloader section size is 0x1000 bytes.  Starts at 0x7000.

The smallest is 0x200 bytes.  Starts at 0x7E00.

If you place SPM at 0x7E00, the BOOTSZ bits won't matter.

Edit: correction

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

Last Edited: Fri. Oct 5, 2018 - 06:26 PM

skeeve wrote:
The smallest is 0x200 bytes. Starts at 0x7E00. If you place SPM at 0xFE00, the BOOTSZ bits won't matter.
Typo?

 "Experience is what enables you to recognise a mistake the second time you make it." "Good judgement comes from experience.  Experience comes from bad judgement." "Wisdom is always wont to arrive late, and to be a little approximate on first possession." "When you hear hoofbeats, think horses, not unicorns." "Fast.  Cheap.  Good.  Pick two." "We see a lot of arses on handlebars around here." - [J Ekdahl]

joeymorin wrote:
Typo?

No, probably not.  App SPM writes must be from legal bootloader area, right?  So if (say) no bootloader, that would be  "safe" address irregardless of BOOTSZ fuse setting.

Note the reference to "fuse settings".  Lock bits and boot lock bits are a different matter.

[hmmm--on second thought one probably needs to pay attention to BLB...]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. Oct 5, 2018 - 05:03 PM

But a 32K micro doesn't have flash at 0xFE00? That's up near the end of a 64K micro.
.
#1 mentions 32U4

Last Edited: Fri. Oct 5, 2018 - 05:37 PM

clawson wrote:

I wrote some words the other day (which turned out at the time to be misguided) about sharing bootloader functions to an application:

https://www.avrfreaks.net/commen...

You may find something of use there. The basic principle here is that the only piece of "shared knowledge" between the app code and the boot code is a 16 bit pointer passed from one to the other and also that each knows the order of entries in an array of function pointers (who's base address is passed as that 16 bit value). The actual routines in the boot code that are shared to the app can actually live anywhere in the bootloader space.

when i tried your method in the other form i came acorss this error

Severity	Code	Description	Project	File	Line
Error		ld returned 1 exit status	SNSBootloader	collect2.exe	0


I wonder why the compiler complained when I tried to have a pointer to the function (do_spm_N) ;

this is what I tried


typedef void(*P_do_spm_N)(void);
P_do_spm_N functions[]={
do_spm_N
};

and this

 void do_spm_N (void)BOOTLOADER_SECTION;

int main(void)
{

TCNT1 = &do_spm_N;
:
:
:
:
................

}

theusch wrote:

joeymorin wrote:
Typo?

No, probably not.  App SPM writes must be from legal bootloader area, right?  So if (say) no bootloader, that would be  "safe" address irregardless of BOOTSZ fuse setting.

Note the reference to "fuse settings".  Lock bits and boot lock bits are a different matter.

[hmmm--on second thought one probably needs to pay attention to BLB...]

yes but  0xFE00  way out of the boot section ,that wont work

joeymorin wrote:

skeeve wrote:
The smallest is 0x200 bytes. Starts at 0x7E00. If you place SPM at 0xFE00, the BOOTSZ bits won't matter.
Typo?

Yes, will edit, though the statement is true as is :-)

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

Last Edited: Fri. Oct 5, 2018 - 07:09 PM

clawson wrote:

I wrote some words the other day (which turned out at the time to be misguided) about sharing bootloader functions to an application:

https://www.avrfreaks.net/commen...

	TCNT1 = &functions;

what did you use TCNT1 , it compiles but it doesn't allow me to load to the MC

sternst wrote:

So actually you have a bootloader and the function do_spm_N is part of it?

Then all this is nonsense:

#define BOOTLOADER_SECTION __attribute__ ((section(".bootloader"))) ;
...
static void do_spm_N (uint32_t address,  uint8_t *data) BOOTLOADER_SECTION;
LDFLAGS += -Wl,--section-start=.bootloader=\$(BOOT_START)
static void (*do_spm_N)(uint32_t address,  uint8_t *data)__attribute__ ((section(".bootloader"))) ;


All you need in the application is a correctly initialized function pointer:

void (*do_spm_N)(uint32_t address, uint8_t *data) = 0xXXXX;

I tried that but it still doesn't work

*Declare*do_spm_N in the application source.

"Define* it with the linker.  --define-symbol or something like that.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

skeeve wrote:

*Declare*do_spm_N in the application source.

"Define* it with the linker.  --define-symbol or something like that.

I am not sure how can I define a function in the linker ?

Never done that before ?

DO I need to do anything with the bit locks ?

the manual says the following

AVATAR_Freaks wrote:

skeeve wrote:

*Declare*do_spm_N in the application source.

"Define* it with the linker.  --define-symbol or something like that.

I am not sure how can I define a function in the linker ?

Never done that before ?

Define the symbol do_spm_N .

To find the correct value, look at the output of avr-nm bootloater.elf .

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

skeeve wrote:

AVATAR_Freaks wrote:

skeeve wrote:

*Declare*do_spm_N in the application source.

"Define* it with the linker.  --define-symbol or something like that.

I am not sure how can I define a function in the linker ?

Never done that before ?

Define the symbol do_spm_N .

To find the correct value, look at the output of avr-nm bootloater.elf .

What should I look for tho in the .elf file ?

AVATAR_Freaks wrote:
l i need to use the rest of my flash memory to save data

Static data?  i.e. known at compile time?  if so, then use flash keyword on your data array to store in flash

If dynamic, at run time, you do know the max writes to flash is about 10k times. i.e. if writing to only once per second, will only be usable for ~3 hours.

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

AVATAR_Freaks wrote:

skeeve wrote:

AVATAR_Freaks wrote:

skeeve wrote:

*Declare*do_spm_N in the application source.

"Define* it with the linker.  --define-symbol or something like that.

I am not sure how can I define a function in the linker ?

Never done that before ?

Define the symbol do_spm_N .

To find the correct value, look at the output of avr-nm bootloater.elf .

What should I look for tho in the .elf file ?

when I look at my .elf file I can't find do_SPM_N ???

I was looking at the linker ,

IS it okay that the .text and the .bootloader sets at the same address  location  ??

Address of section .text set to 0x7000

AVATAR_Freaks wrote:
I was looking at the linker ,
IS it okay that the .text and the .bootloader sets at the same address  location  ??
Only if one is empty.

Note that in the normal course of events, the bootloader's .text section is in the AVR's bootloader section.

The bootloader is a complete program.

If you wish to have your application use a function in the bootloader.

The application will have to know its address, hence avr-nm .

If you do not know the function's name, that would be a problem.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

skeeve wrote:

If you wish to have your application use a function in the bootloader.

The application will have to know its address, hence avr-nm .

If you do not know the function's name, that would be a problem.

Yes I know my function name, but when I run avr-nm I cant see my function, Hence I don't know the address ??

AVATAR_Freaks wrote:
Yes I know my function name, but when I run avr-nm I cant see my function, Hence I don't know the address ??
You sure that it is a function and not a macro?

If all else fails look at the bootloader's .lss file and look for the SPM instruction.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

Last Edited: Wed. Oct 10, 2018 - 06:37 PM

let me ask a simple question, I want to do a simple test

I would like to have a CONSTANT value in my boot loader at specific adress and read it from my application how can DO that ?

can I do somthin like

static uni32_t = 0x5a5a

how Can i read it from the application ?

AVATAR_Freaks wrote:

let me ask a simple question, I want to do a simple test

I would like to have a CONSTANT value in my boot loader at specific adress and read it from my application how can DO that ?

can I do somthin like

static uni32_t = 0x5a5a

how Can i read it from the application ?

In any case, the application needs the address.

If it's in flash, you have roughly the situation you have with do_spm_N.

You'll need LPM.

In-ram also works.

You will need to go through some contortions to ensure

neither code writes over it before the app reads it.

End of RAM is probably best.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

If you want to "share" a value from boot to app the best place to pass it is one of the SFRs. Modern AVRs have GPIOR0, GPIOR1, GPIOR2 for this purpose. Both "sides of the fence" already know the (unchanging) address of these storage locations.

Having said that you can actually use any (otherwise unused) SFR for this. In the past I have used TWAR and also TCNT1 as 8 or 16 bit registers that can just be used to pass some data.

clawson wrote:
f you want to "share" a value from boot to app the best place to pass it is one of the SFRs. Modern AVRs have GPIOR0, GPIOR1, GPIOR2 for this purpose. Both "sides of the fence" already know the (unchanging) address of these storage locations.
I'd thought they were wiped out by a watchdog reset.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

Nothing to stop the bootloader setting the register AFTER the WDT reset (assuming there even is one).

As I've shown elsewhere, if the boot wants to share a table of function pointers to make certain routines (UART, SPM etc) available to the app, so it can save some of its flash, then the boot can pass the 16 bit base address of the dispatch table in some "known place" such as a 16 bit SFR. This negates the need for app/boot to share "internal addresses" such as might happen if, otherwise, the bootloader decided to fix such a table at 0x7FF0 or something like that. The only "common thing" is that single 16 bit pointer and a shared knowledge of the order of entries in the function pointer array.

clawson wrote:

Nothing to stop the bootloader setting the register AFTER the WDT reset (assuming there even is one).

As I've shown elsewhere, if the boot wants to share a table of function pointers to make certain routines (UART, SPM etc) available to the app, so it can save some of its flash, then the boot can pass the 16 bit base address of the dispatch table in some "known place" such as a 16 bit SFR. This negates the need for app/boot to share "internal addresses" such as might happen if, otherwise, the bootloader decided to fix such a table at 0x7FF0 or something like that. The only "common thing" is that single 16 bit pointer and a shared knowledge of the order of entries in the function pointer array.

skeeve wrote:

clawson wrote:
f you want to "share" a value from boot to app the best place to pass it is one of the SFRs. Modern AVRs have GPIOR0, GPIOR1, GPIOR2 for this purpose. Both "sides of the fence" already know the (unchanging) address of these storage locations.
I'd thought they were wiped out by a watchdog reset.

Okay so my understanding is if I use one of the sfrs or GPIOR I can pass a value between the application and the bootloader right? I will try that.

BTW, MY bootloader based on the Catrerina Bootloader , with some editing to it.

SHould I put the bootloader here if you guys wanna take a look at it ?

If you want to "publish" code you are far better off doing it on github, Microchip "Spaces", or similar.

(actually I see that Sparkfun and Adafruit each already have versions of "Caterina" on github too).

clawson wrote:

If you want to "publish" code you are far better off doing it on github, Microchip "Spaces", or similar.

(actually I see that Sparkfun and Adafruit each already have versions of "Caterina" on github too).

Yes, I know I want to have as a reference. Have you ever used the caterina or went through it ?

I am just afraid that there is something in that code disabling SPM , because every time i try to use my own function from the application the board freezes.

Actually looking at the caterina, it uses

/* Undo TIMER1 setup and clear the count before running the sketch */
TIMSK1 = 0;
TCCR1B = 0;
TCNT1H = 0;        // 16-bit write to TCNT1 requires high byte be written first
TCNT1L = 0;
/

so I can't use TCNT1