Where is the Default Linker Script

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

Hey Guys, I 'm looking to change the linker script but I want to know what is the default linker script used so I can work of it .

I was able to find the ldscripts folders, but there is foure folder named ldscripts -one under avr8, avr32 and 2 under  arm-none. I am assuming the ones under arm is irrelevant. SO which one is it the avr 32 or the avr 8.

 

While compiling I can see the ld.exe path is "c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe"

So I'm assuming the AVR8 one RIGHT?

 

However the avr8\lib\ldscripts contains about 12 linker_scripts which one is being used for the atmerga32u4, is there  any clue in the script that will tell me?

the names or the scripts are 

anyone knows?

avr1.x
avr2.x
avr3.x
avr4.x
avr5.x
avr6.x
avr25.x
avr31.x
avr35.x
avr51.x
avrtiny.x
avrxmega1.x
avrxmega2.x
avrxmega3.x
avrxmega4.x
avrxmega5.x
avrxmega6.x
avrxmega7.x

 

This topic has a solution.
Last Edited: Wed. Oct 31, 2018 - 01:26 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you add -Wl,--verbose to the linker arguments, then it should output which linker script it used...

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

Yes that did it

it uses 5avr.xn

thanks

 

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

also i see where it is pointing to, but it doesn't seem correct the atmerga memory is 32K

and in the file it says 128K should i change it ?

the rerson i am doing that is because i keep getting overlapping error and trying to fix that 

__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xffa0;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
__SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : 1K;
__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : 1K;
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
  data   (rw!x) : ORIGIN = 0x800060, LENGTH = __DATA_REGION_LENGTH__
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
  signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
  user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__
}

 

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

You aren't reading that correctly. In fact in the good old says the avr5.x file used to say:

D:\WinAVR-20100110\avr\lib\ldscripts>type avr5.x
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
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
}

"avr5" architecture is (at least) all these:

D:\WinAVR-20100110\avr\lib\avr5>dir crt*.o /w
 Volume in drive D is DATA
 Volume Serial Number is 1CF4-86D6

 Directory of D:\WinAVR-20100110\avr\lib\avr5

crt90pwm216.o   crt90pwm316.o   crt90scr100.o   crtat94k.o      crtcan128.o     crtcan32.o      crtcan64.o
crtm128.o       crtm1280.o      crtm1281.o      crtm1284p.o     crtm128rfa1.o   crtm16.o        crtm161.o
crtm162.o       crtm163.o       crtm164a.o      crtm164p.o      crtm165.o       crtm165a.o      crtm165p.o
crtm168.o       crtm168a.o      crtm168p.o      crtm169.o       crtm169a.o      crtm169p.o      crtm169pa.o
crtm16a.o       crtm16hva.o     crtm16hva2.o    crtm16hvb.o     crtm16m1.o      crtm16u4.o      crtm32.o
crtm323.o       crtm324a.o      crtm324p.o      crtm324pa.o     crtm325.o       crtm3250.o      crtm3250p.o
crtm325p.o      crtm328.o       crtm328p.o      crtm329.o       crtm3290.o      crtm3290p.o     crtm329p.o
crtm329pa.o     crtm32c1.o      crtm32hvb.o     crtm32m1.o      crtm32u4.o      crtm32u6.o      crtm406.o
crtm64.o        crtm640.o       crtm644.o       crtm644a.o      crtm644p.o      crtm644pa.o     crtm645.o
crtm6450.o      crtm6450a.o     crtm6450p.o     crtm645a.o      crtm645p.o      crtm649.o       crtm6490.o
crtm6490a.o     crtm6490p.o     crtm649a.o      crtm649p.o      crtm64c1.o      crtm64hve.o     crtm64m1.o
crtusb1286.o    crtusb1287.o    crtusb646.o     crtusb647.o

where you can see there are 16K, 32K, 64K and 128K devices so:

  text      (rx)   : ORIGIN = 0, LENGTH = 128K

caters for all of them. It doesn't mean the length is fixed at 128K, it means the maximum size the text (flash) can be for "avr5" devices is 128K.

 

It's true that because this one script is used for so many devices that if you build code for a 32K micro and you actually build 35K of code you will not get a linker warning about "text is too large". You will only start to see that if you are building for 128K devices and build 129K+ code. (actually even just 1 byte over 128K).

 

This might bother some folks so in recent years the same stuff has been changed to:

__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
  text   (rx)   : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__

This is saying that if the symbol "__TEXT_REGION_LENGTH__" has been defined for a device then use that as the upper limit then use that, but otherwise (like that 10 year old compiler I just showed) just treat all avr5 as "up to 128K".

 

You can now imagine a scenario where you build for a 32K device so __TEXT_REGION_LENGTH__ is defined to "32K" for that device and now, when you link the code if it comes to over 32K you will get a warning.

 

However I have looked at this and I personally cannot see where these _TEXT_REGION_LENGTH__ values are defined. As the symbol starts with two underscores it suggests it is owned/defined by the toolchain. So this would seem to suggest that avr-ld may have a large table built into it with all the -mmcu device names and their region sizes for "test" and "data" and "eeprom" and so on. But I've looked at the recent source for avr-ld and I cannot see this. Maybe it's the case that the compiler somehow passes a -D into the link??

 

Anyway don't sweat it unless you are REALLY concerned about not getting an overflow warning when you link (but I think other tools in AS7 police that anyway don't they?)

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

Yes that make alot of sense now, thanks alot

 

But I though i can use the linker script to over come my overlapping problem when defininf the new Trampoline table 

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

Sure you can use a linker script to add an additional load section to the text region but don't do it by editing the master copy of avr5.x in the ldscripts directory. If you edit that you make changes that will affect all future avr5 projects you work on. Instead copy avr5.x to your local project directory and to avoid mistakes in editing give it a different name like copyavr5.x. Then make your edits in that. Then you later build pass "-T copyavr5.x" as part of the link command (add -Wl, to the front if using avr-gcc). That says "override the default ldscripts/avr5.x and use this other file instead". You can do whatever damage you like as you can always restore it from the master (assuming you don't use revision control)

Last Edited: Wed. Oct 31, 2018 - 02:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes that is what i Am doing but how can i add extra sections tho? 

lets say i am adding three section , do I need to do 

 

SECTIONS
{
  . = 0x7000;
  .apitable_trampolines : { *(.apitable_trampolines) }
  . = 0x7017;
  .apitable_jumptable : { *(.apitable_jumptable) }
  . = 0x7032;
  .apitable_signatures : { *(.apitable_signatures) }

}

and add this to the makefile 

# known FLASH addresses - these should not normally be user-edited.
BOOT_SECTION_LD_FLAG  = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
# Begninng
BOOT_API_LD_FLAGS     = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 4*1024)
BOOT_API_LD_FLAGS    += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable,   BootloaderAPI_JumpTable,   4*1024-12)
BOOT_API_LD_FLAGS    += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures,  BootloaderAPI_Signatures,  4*1024-24)

 

Last Edited: Wed. Oct 31, 2018 - 03:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want fixed addresses why are you trying to do it with a linker script and not simply -section-starts ?

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

clawson wrote:

If you want fixed addresses why are you trying to do it with a linker script and not simply -section-starts ?

 

when i use --Section-start  it give me the overlapping errro  message  

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

There is only one flash section you don't have control over the placement and size (that is "text" which is usually located at 0x0000). You can tell from the map file how big it is and hence where it ends so just set your stuff in fixed section-starts to use locations beyond the end of that (and that also don't overlap). 

 

In fact a good strategy is generally to let the linker place text (.text and .data) from the start up then for your own manually placed sections (assuming fixed sizes) start at the end of flash and work back placing them on boundaries so there are no overlaps.

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

yes I tried that, but still over lapped cuz i think i have long cod... 

DO yo u know if the atmega2u4 bootloader can start from 6800

i read ana rticla saying :

 

# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the
# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum
# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices.

 

is that true?

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

AVATAR_Freaks wrote:
i think i have long cod... 
If that's true than on the principle that you can't fit a quart into a pint pot there is no amount of messing with linker scripts or -section-starts that can magically reduce the size of the code so it all fits - you have to optimise the code you write to do that or pick a larger AVR.
AVATAR_Freaks wrote:
DO yo u know if the atmega2u4 bootloader can start from 6800
You could give in and simply read the datasheet you know?

 

Personally I always find it very confusing that Atmel insist on using words not bytes in a table like this. If you take the last column and double the values there you get the byte addresses where the bootloader boundary can be placed:

3F00 -> 7E00
3E00 -> 7C00
3C00 -> 7800
3800 -> 7000

So, no the bootloader cannot start from 0x6800. It has to be one of 4K, 2K, 1K or 0.5K in size. To start at 0x6800 suggests a 6K bootloader.

 

Now what you can do if you write "too much" bootloader is to split it. Set the BOOTSZ for the 4K value so it starts at 0x7000 and arrange for the reset vector to be at exactly 7000 but you can put some of the non-essential, non-SPM code down below it in the 2K from 0x6800 to 0x7000.

 

Of course, in a 32K micro if you use 6K for the bootloader you only leave 26K for the application.

 

I just went back and read:

# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the
# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum
# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices.

So, yes, that says exactly the same thing as I just did.

 

My own personal belief is that an AVR bootloader should never need anything like 6K. If it does it is almost certainly doing something far too complex. When you ship a product the only piece of the code that must be 100% bug free on the day you ship is the bootloader (the rest of the code can be replaced later - kind of the whole point of using a bootloader!). The larger it gets the less likelihood there is that it's 100% error free. That's an issue because the bootloader itself (especially a "big one") could never be updated/replaced. Most bootloaders for AVR can comfortably fit in 0.5K though I understand that adding a USB stack can grow this a bit but for motivation look at the PJRC "halfkay" USB bootloader used in their "Teensy" projects.

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

Yes I know the bootloader only can e up too 4k but I was hoping i can use the 6k. But it sound like I can do that. If i but all my spm need in the 7000 the rest still can go to the oher 2k starting from 6800 and that makes mr gain to more 2ks, did i understand that right?

 

also what is the best practise to rearrange the vectors i have never done that i always thought the compiler take care of that. this is how my elf looks like . doe that means vectors from  1:50 is empt has no information ? 

 

00007114 t .do_clear_bss_loop
00007116 t .do_clear_bss_start
00007124 T __bad_interrupt
008001f4 B __bss_end
0080019e B __bss_start
000070ea T __ctors_end
000070ea T __ctors_start
0080019e D __data_end
00007fee A __data_load_end
00007f50 A __data_load_start
0000ffa0 A __DATA_REGION_LENGTH__
00800100 D __data_start
0000710c T __do_clear_bss
000070f6 T __do_copy_data
000070ea T __dtors_end
000070ea T __dtors_start
00810000 N __eeprom_end
00010000 A __EEPROM_REGION_LENGTH__
00000003 A __FUSE_REGION_LENGTH__
00000000 W __heap_end
000070ea W __init
00000400 A __LOCK_REGION_LENGTH__
00000400 A __SIGNATURE_REGION_LENGTH__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003e a __SP_H__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003d a __SP_L__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
0000003f a __SREG__
00000aff W __stack
00007f4e t __stop_program
00007f14 T __tablejump2__
00008000 A __TEXT_REGION_LENGTH__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
00000000 a __tmp_reg__
000070c0 T __trampolines_end
000070c0 T __trampolines_start
00000400 A __USER_SIGNATURE_REGION_LENGTH__
00007124 W __vector_1
00007a66 T __vector_10
00007124 W __vector_11
00007124 W __vector_12
00007124 W __vector_13
00007124 W __vector_14
00007124 W __vector_15
00007124 W __vector_16
00007246 T __vector_17
00007124 W __vector_18
00007124 W __vector_19
00007124 W __vector_2
00007124 W __vector_20
00007124 W __vector_21
00007124 W __vector_22
00007124 W __vector_23
00007124 W __vector_24
00007124 W __vector_25
00007124 W __vector_26
00007124 W __vector_27
00007124 W __vector_28
00007124 W __vector_29
00007124 W __vector_3
00007124 W __vector_30
00007124 W __vector_31
00007124 W __vector_32
00007124 W __vector_33
00007124 W __vector_34
00007124 W __vector_35
00007124 W __vector_36
00007124 W __vector_37
00007124 W __vector_38
00007124 W __vector_39
00007124 W __vector_4
00007124 W __vector_40
00007124 W __vector_41
00007124 W __vector_42
00007124 W __vector_5
00007124 W __vector_6
00007124 W __vector_7
00007124 W __vector_8
00007124 W __vector_9
00007000 W __vector_default
00007000 T __vectors
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
00000001 a __zero_reg__
0080019e D _edata
008001f4 N _end
00007f50 T _etext
00007f4c T _exit
00006800 T Boot_AUX_Trampoline
00800100 D bootKey
00007946 T BootloaderAPI_FillWord
00007ff0 t BootloaderAPI_FillWord_Trampoline
00007ff4 T BootloaderAPI_JumpTable
00007ff8 T BootloaderAPI_Signatures
00007ff0 T BootloaderAPI_Trampolines
00007ff2 t BootloaderAPI_UNUSED1
00007898 T CacheDescriptor
         U CALLBACK_HIDParser_FilterHIDReportItem
000078b4 T CALLBACK_USB_GetDescriptor
00007340 T CDC_Task
00800156 D ConfigurationDescriptor
008001a4 b CurrAddress
000070d8 T DeviceDescriptor
0000788a t do_spm
00007f20 T eeprom_read_byte
00007f30 T eeprom_write_byte
00007f32 T eeprom_write_r18
00007986 T Endpoint_ClearStatusStage
00007960 T Endpoint_ConfigureEndpoint_Prv
00007c78 T Endpoint_Read_Control_Stream_LE
00007bc8 T Endpoint_Write_Control_Stream_LE
000072cc T EVENT_USB_Device_ConfigurationChanged
00007ef0 W EVENT_USB_Device_Connect
000072e4 T EVENT_USB_Device_ControlRequest
00007ef0 W EVENT_USB_Device_Disconnect
00007ef0 W EVENT_USB_Device_Reset
00007ef0 W EVENT_USB_Device_StartOfFrame
00007ef0 W EVENT_USB_Device_Suspend
00007ef0 W EVENT_USB_Device_WakeUp
00007f4c W exit
00007126 t FetchNextCommandByte
00800152 D LanguageString
000071b4 T LEDPulse
00800103 d LineEncoding
008001e8 B LLEDPulse
000077e6 T main
0080010a D ManufNameString
0000711c T pre_main
0080012e D ProductString
00800102 d RunBootloader
008001a0 B RxLEDPulse
000070c0 T SerialNumString
000071e6 T SetupHardware
008001a8 b SramDeviceDescriptor
008001ba b SramSerialString
00007190 T StartSketch
0080019e B Timeout
008001a2 B TxLEDPulse
008001ec B USB_ControlRequest
008001ea B USB_Device_ConfigurationNumber
00007cf4 T USB_Device_ProcessControlRequest
00007ef0 T USB_Event_Stub
00007a36 T USB_Init
00007a5c T USB_INT_ClearAllInterrupts
00007a4c T USB_INT_DisableAllInterrupts
008001eb B USB_IsInitialized
000079c0 T USB_ResetInterface
00007ef2 T USB_USBTask
00007154 t WriteNextResponseByte

 

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

AVATAR_Freaks wrote:
i think i have long cod...

 

I'm losing track.  How long is the code?  Is it in fact a bootloader?  Or some kind of "BIOS" equivalent, given all the mention of trampolines?

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.

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

it is a bootloader, I am using the  trampolines  so i can write to flashmemory , from application

that is my goal.

 

The boatlaoder is about 4220 KB 

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

AVATAR_Freaks wrote:
The boatlaoder is about 4220 KB
Had to capture that Freudian slip! It sure is a "boat loader" if it's really 4.2MB !!

 

Anyway the only thing that HAS to b at 0x7000 assuming BOOTRST to the largest BOOTSZ is a reset jump. I kid of hope you won't have a vector table in a bootloader (ie no interrupts) but if you do then you have two options. One would be to build gcrt1.S into your own code (and -nostartfiles) and then position that to be at 7000. The other is to effectively build two programs. One with up to 4K that sits at 7000 and has the "normal" reset and IVT, then the "ancillary" stuff in the 2K below. Connect them with the kind of dispatch table I have mentioned in your other threads - the only connection between two programs has to be one 16 bit value which is a pointer to the base of a despatch table full of the other function pointers. Obviously the "2K bit" would use -nostartfiles so it doesn't even have to have a "main()". Just a set of functions then this table that points to each function in turn. The 4K bit either already "knows" the location of the dispatch table or another idea is to sprinkle it with cookies. Then have the 4K code do a scan through the 2K area to find the cookies and hence the table.

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

Tell why your bootloader is 2x/3x/4x the size of most bootloaders.  I thought that Cliff's SD bootloader was about half that.

 

Certainly not my area of expertise, but if you are using the alternate vector table in the bootloader then you already know exactly the address of each vector entry (assuming you tell the app the start of the bootloader).  Then you take unused vectors and have them point to the needed routines as ersatz ISRs.

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: Thu. Nov 1, 2018 - 05:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
I thought that Cliff's SD bootloader was about half that.

https://spaces.microchip.com/gf/...

I wanted to write a bootloader that would fit in 2KBytes of a mega16

And indeed it is.  What is the bootloader source of firmware?

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.

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

I engineered my SD bootloader to fit in 1K. I then went a bit over-board on extras and with them all on you need a 2K bootloader section, but if you change the config.h you can bring it back under 1K.

 

I do understand why a 32U4 bootloader might be bigger - it has full USB support in it. Having said that Dean gets most of his bootloaders in LUFA into 4K or less.

 

As I say if you want to see the pinnacle of USB bootloader engineering you need to see the Tennsy bootloader from PJRC. They call it "halfkay" because it fits into 512 bytes. Apparently it's closed source in extremely well honed, hand crafted Asm but it proves you can can get all that's needed for USB bootloader support into 0.5K. I think a "mortal" should be able to get into the region of 1K..2K.

 

Or for an easy life just get LUFA and build any of Dean's bootloaders which are all bound to fit within 4K. The "obvious choice" would probably be "DFU" as it's the one that Atmel also use.

 

In fact Atmel are another possible source - they have DFU bootloaders (AVR1916) for all their USB devices that all fit in 4K. The only "gotcha" is that they only supply them as IAR projects/source. They do that because IAR is the only thing that can build them "tight" enough. The good news is that you don't have to pay the usual £3,000 to buy a copy of IAR for AVR. The "kickstart" version is "free" and can build anything up to 4K so the bootloaders fit nicely. Only downside is it could be a bit "tight" if you want to start adding functionality over and above the default.

Last Edited: Thu. Nov 1, 2018 - 05:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It sounds a bit farfetched that given an AVR8 chip model with USB support, a trained monkey with the patented 'Freaks typewriter couldn't do simple send-receive (only receive needed?)  in about the same space that you need to do the useful SD card work.   But hey--what do I know.  I'd probably do something stupid like create a .EEP file with the needed addresses.

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.

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

Okay SO I was able to take care of the overlapping issue and the size issue. I followed the instructions . Now I realized that my overlapping issue was not a coding error but it was due to the big size of the bootloader. (as mentioned above)  

I'm using the caterina bootloader and the lUFA Drivers. To fix that I followed the technique which was used in another project that comes with the LUFA  folder which called (BootloaderMassStoage). 

In summery what i did is:-

I created an AUX_Bootloader starting at 6800 and moves all the function to it then Put my table and trampolines (which contains the function i will need to write to flash memory) in the 7000 area so i can call the SPM and uses those functions to write to flash memory. at this moment the bootloader compiles and no over lapping issue since i moved all the function to the 6800 area, However that been said, I haven't yet tested the writing to flash or the functionality of the bootloader. I ordered an ATMEL-ICE emulator to debug the codes step by step. I will update once I know the results. 

 

Also  the total size come to 2598 Bytes half the size because I moves about 2k to start from 6800, now every one is happy, but writing to flash LOL

 

 

 

 

 

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

i got The Atmel-ICE an d i AM not sure how to use it yet. COuldn't find any tutorials about using with arduino boards, i have few question

 

1- can I use it to debug the application and the bootloader ?

2- How can I do that using JTAG 

 

 

do you know if any tutorial uses (arduino Micro) or any thing similar 

 

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

Okay I found the soution to step by step code using the Atmel ICE with Arduino Mico,

her is it for future references 

 

https://www.ba0sh1.com/blog/2013...

 

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

If i have a function in the bootloader that I call from the application , how can I debug that if my boot loader and my app is separate projects? 

 

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

They are two separate programs. Debug them as such. To test a function in the bootloader call it from the bootloader when testing.

Last Edited: Wed. Nov 7, 2018 - 01:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

They are two separate programs. Debug them as such. To test a function in the bootloader call it from the bootloader when testing.

 

TO debug the application part, do I need to upload the bootloader first ?

 

 

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

If the app is to call the bootloader functions when it executes then, yes, that binary needs to be in the flash at the same time (otherwise it won't come back!). But the point is that you cannot really do symbolic debugging of both app and boot code at the same time. So when it disappears off into the upper flash you might was well step over the call as you'll just be looking at raw asm otherwise - but that should not matter as those functions should already have been proven when you developed/debugged the bootloader.

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

clawson wrote:

If the app is to call the bootloader functions when it executes then, yes, that binary needs to be in the flash at the same time (otherwise it won't come back!). But the point is that you cannot really do symbolic debugging of both app and boot code at the same time. So when it disappears off into the upper flash you might was well step over the call as you'll just be looking at raw asm otherwise - but that should not matter as those functions should already have been proven when you developed/debugged the bootloader.

 

Okay I see! I'll try that

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

Guys :

what is wrong with this code, why The memory is not updating ? If I define my function as void and  the page inside the function (uint32_t page = 0x0410; ) it works and the memory gets updated.

But If tried to pass the page  through the function do_spm_N(page);  as below it don't 

 

int main(void)
{
    
    
uint32_t page;
	page =0x0410;
	do_spm_N(page);
    
    
}



void do_spm_N(uint32_t page) {
	
    uint8_t sreg;
	uint16_t i;
    // Disable interrupts.
	//uint32_t page = 0x0410;
    sreg = SREG;
    cli();
    eeprom_busy_wait ();
    boot_page_erase (page);
	boot_spm_busy_wait ();      // Wait until the memory is erased.
	boot_page_fill (page , 0x5b5b);
    boot_page_write (page);     // 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
    // to the application after bootloading.
    boot_rww_enable ();
    // Re-enable interrupts (if they were ever enabled).
    SREG = sreg;
	
	
	
}

  header fiile 

 

#ifndef FlashAcess.h
#define FlashAcess.h

	#define BLOCKSIZE SPM_PAGESIZE
    #define ADDR_T unsigned int

/* SPM do function to write data to flash memory */


		 void do_spm_N (uint32_t page)__attribute__ ((naked))  __attribute__ ((section (".bootloader")));
		 

  
  
  
#endif

 

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

Great - just type a long reply which was lost.

 

Bottom line is 0x410 cannot be valid as it's not a multiple of SPM_PAGESIZE. For 32U4 that is:

C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr>grep SPM_PA iom32u4.h
#define SPM_PAGESIZE (128)

so valid values are going to be:

page 0  0x0000
page 1  0x0080
page 2  0x0100
page 3  0x0180
page 4  0x0200
page 5  0x0280
page 6  0x0300
etc.

That is it has to end in 00 or 80 to be a valid page address, 0x410 is not.

 

If you are working from the example boot_program_page() given here in the user manual:

 

https://www.nongnu.org/avr-libc/...

 

then you aren't the first to be bitten by this thinking "page" was a page number and not an actual page address. (don't ask me how I know this!)

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

clawson wrote:

 

so valid values are going to be:

page 0  0x0000
page 1  0x0080
page 2  0x0100
page 3  0x0180
page 4  0x0200
page 5  0x0280
page 6  0x0300
etc.

 

 

https://www.nongnu.org/avr-libc/...

 

 

yes this is the example I am working from.

So wait, should I pass 0x0300 or 6  ?

but regardless even if i pass 0x0400 or 0x0480 it doesn't write it and write it to 0x0000 and 0x0001  ? I wonder if i should be sending the value in dec not hex? 

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

As I say it's an ADDRESS not a page number. So it you wanted to reprogram flash from 0x300 to 0x37F, which is page 6 you would pass 0x300 to the function.

 

But your code:

    uint8_t sreg;
	uint16_t i;
    // Disable interrupts.
	//uint32_t page = 0x0410;
    sreg = SREG;
    cli();
    eeprom_busy_wait ();
    boot_page_erase (page);
	boot_spm_busy_wait ();      // Wait until the memory is erased.
	boot_page_fill (page , 0x5b5b);
    boot_page_write (page);     // 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
    // to the application after bootloading.
    boot_rww_enable ();
    // Re-enable interrupts (if they were ever enabled).
    SREG = sreg;

is so similar to the example in the manual:

void boot_program_page (uint32_t page, uint8_t *buf)
{
    uint16_t i;
    uint8_t sreg;
    // Disable interrupts.
    sreg = SREG;
    cli();
    eeprom_busy_wait ();
    boot_page_erase (page);
    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 = *buf++;
        w += (*buf++) << 8;
    
        boot_page_fill (page + i, w);
    }
    boot_page_write (page);     // 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
    // to the application after bootloading.
    boot_rww_enable ();
    // Re-enable interrupts (if they were ever enabled).
    SREG = sreg;
}

then why do you just kind of "half use it"? Why not implement the entire code they give in the manual? You would then call it with something like:

uint8_t page_buff[SPM_PAGESIZE];

sprintf(page_buff, "Hello Cruel World");

boot_program_page(0x300, page_buff);

You should then find that the first bytes of the flash between 0x300 and 0x37F are "Hello Cruel World".

 

Of course all the code of boot_program_page() (which includes the SPM) has to be located in the BLS but the code that calls it could be located anywhere.

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

clawson wrote:
why do you just kind of "half use it"? Why not implement the entire code they give in the manual? You would then call it with something like:

 

Well I tried to use it, but it didn't work , so i figure to start simple and work my way up ..

still not working tho lol 

 

even when i use do_spm_N (0x400)

it still but the info in 0x000  ? i dont; know why 

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

Do you own a JTAG?

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

clawson wrote:

Do you own a JTAG?

 

Yes I am using ATMEL ICE and , ARduino Micro and I used the following directions to connect. SO i can debug line by line 

 

https://www.ba0sh1.com/blog/2013...

 

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

Then you can step every opcode and see where the operation deviates from the planned path.

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

Yes that is what I am trying to do. But for some unknown reason I don't know why when I startdebuging and break (ALt F5) I see the memory location 0x00 is updated when I step on my code step by step I don't see the flash memory updating.

for example when i goto 

boot_page_erase (page); the location doesn't gets erased  (and the manual says that this function Erases the flash page that contains address)

and when I reach   boot_page_write (page);  nothing gets written ..

 

 

I though I can see the memory updating live with each step. 

 

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

AVATAR_Freaks wrote:
when I step on my code step by step I don't see the flash memory updating.
AS7 caches flash by default (so it doesn't have to re-read to refresh memory displays every time it stops execution). It does this on the basis that it does not expect the flash to change. Working on SPM code is a "special case" so you have to switch the caching off to see updated results for this very particular kind of debugging.

 

I forget where it is but it's somewhere under the options available from the Debug menu. I don't think I can test it here without an ICE as I only have the simulator and I don't think it has the option.

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

OK so just connected an Atmel-ICE so I could check this out. the option is here:

 

 

Make sure that is unticked when working on SPM. (put it back afterwards or future debugging may be "slow")

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

clawson wrote:
Working on SPM code is a "special case" so you have to switch the caching off to see updated results for this very particular kind of debugging.

 

Yessss, Now it works . Now I can see my memmory changing and when I pass the values it gets updated. Now I can debug my code 

Thanks alot!

 

Gonna get back to update my debug my code now

Last Edited: Fri. Nov 9, 2018 - 02:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I finished debugging my bootloader and it is doing what I am asking it to do.

Now in order to debug my application i created a separate project and called it test.

and simply i am calling the do_spm_N () function to test it.

Now when I start debugging and break , will the ICE erase my chip, how i tell it  is only an application don't delete my bootloader.

Under tools there programming setting and Erase entire chip is selected , I think I need to change the settings but which setting should work for my case 

or that is something totally different ?

 

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

Sadly the options for tiny/mega are not as advanced for later chips (which support selective erase) so the only real option is just to skip erasing all together.

 

In fact I'd be tempted to combine the boot+app code - program that all first then start debugging with "skip programming" so it just uses the code in flash that is already "in situ" - it should still load the symbols from the current project's ELF file (which should match the layout in one of the two sections).

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

 

Oh that is bummer !!

But if i choose skip programming it errors out 

 

 

 

whe you say Boot+app , do you mean make them all in the same project ? is that possible ?

or do you mean just merging the hex ?

Last Edited: Fri. Nov 9, 2018 - 04:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK then here's an idea but I can't say I'm totally convinced - however I did something like this in the past (to make an AS4 asm program and a GCC program work together).

 

1) build the boot code

2) When you have the boot.hex use objcopy ("-I ihex -O binary") to create a boot.bin from boot.hex

3) use a tool such a xxd to convert boot.bin into an initialised C array in something like boot.c

4) add that to your app project but use __attribute__((section(".boot"))) or similar to assign the array in boot.c to some named section

5) use -Wl,-section-start=.boot=0x1234 to set the location of the boot binary to the BLS address (replace 1234)

6) build app project. Now it effectively places both the app code and the boot code but as one single ELF file that can be programmed/debugged.

7) if this works...

8) ... I'll be astonished !

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

LOL this is a long process but I will try it ..

but would be easier if I change my programming settings to something else :- here is the options

=I am not sure what they actually do , but if i selected managed by script I can see both the bootloader and the app in the hex but i am not sure what is going on there

OR I can Just use the :program with custom tool" option 3 and make it only program the application part right ??

?

 

1- Erase entire chip

2- managed by script 

3-program with custom tool

4- Skip programming 

Last Edited: Fri. Nov 9, 2018 - 04:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's a question for Atmel (or their user manual at least). I haven't a clue what all those options mean or how they are used.

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

ALright guys so now I'm trying to troubleshoot a simple application code.

turn on the Rx LD and TX LED , but it is not working

here is mycode. What am I missing ?

test.h


#ifndef TEST_H_
#define TEST_H_

#define L_LED_OFF()		PORTC &= ~(1<<7)
#define L_LED_ON()		PORTC |= (1<<7)

#define TX_LED_OFF()	        PORTD |= (1<<5)
#define TX_LED_ON()		PORTD &= ~(1<<5)
#define RX_LED_OFF()	        PORTB |= (1<<0)
#define RX_LED_ON()		PORTB &= ~(1<<0)




#endif /* TEST_H

 

Now here is my main.c


#include <avr/io.h>
#include "test.h"


int main(void)
{
    /* Replace with your application code */
    while (1) 
    {
		 L_LED_ON();
		 TX_LED_ON();
		 		
    }
}

I am excpecting that the TX turns on, but it isnot working ??

 

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

AVATAR_Freaks wrote:
What am I missing ?
DDR registers!

 

(they default to inputs so don't expect to light LEDs until you have switched outputs - you need to set DDRC.7 and DDRD.5)

Last Edited: Tue. Nov 13, 2018 - 01:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh yes I totally forgot that they default to input.

Thanks

Clawson

 

 

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

clawson wrote:
2) When you have the boot.hex use objcopy ("-I ihex -O binary") to create a boot.bin from boot.hex

 

My make file generates a boot.bin that should be the same right?

 

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

As long as the contents as well as the name are .bin (ie binary) then that should be fine. For "xxd" go to the download site for "vim for windows" and get one of the .zip files. The xxd.exe is just separate within the .zip file. Use in the form:

xxd -i file.bin file.c

It will create a C source file that is the binary contents as a C array.