Miscellaneous questions on customizing bootloader of mega4809

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

 

Trying to customize the bootloader based on AVR109 , the task is as difficult as I thought:)

Hope your guys can help me.

1)the pagesize  (clarified:128 bytes)

Which one is right in bootloader?

 

2)how to burn bootloader to the right place? (clarified)

For mega4809 + Atmel studio: just program as usual,burn with programmer. (westFW provided a good start point)

Need define new location for .text while building firmware, the value should be BOOTEND*256+1

 

This topic has a solution.
Last Edited: Wed. Nov 24, 2021 - 08:11 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The BOOTEND and APPEND fuses determine the section sizes/scheme. If you wanted a bootloader that is 2k in size, you would set BOOTEND to 8 (8*256=2048), and APPEND to 0 (which then means APPCODE uses the remaining space).

 

You can write to flash from the code in the bootloader section, but only to flash in the other section(s). Since your bootloader is 2k (0x4000 to 0x47FF), you would then be writing to the app section at 0x4800 and beyond (using the data space addresses). When writing to flash in the data space, you are actually writing to a page buffer (128B), and eventually when you want to get that page buffer programmed to flash via an nvmctrl command, the last write address used will determine which flash page to program. This of course means you have to stay inside a page buffer range of writes before doing the nvmctrl command.

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

Thank you so much.

You begin to work so early?

 

I misunderstand the "pages" & "blocks":
pages: write operation of flash must be done in pages, that is 128 bytes per time for mega4809;

blocks: divide the flash must in blocks, that means boot/app code/app data must be integer multiples of 256 for mega4809.

 

When writing to flash in the data space, you are actually writing to a page buffer (128B), and eventually when you want to get that page buffer programmed to flash via an nvmctrl command, the last write address used will determine which flash page to program. This of course means you have to stay inside a page buffer range of writes before doing the nvmctrl command.

 I don't get the meaning exactly,studying.

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

A block is the size they use to divide up the flash sections and has nothing to do with pages. Once you decide how big your bootloader is going to be, you set the fuse values mentioned earlier to the values you want, and these values are in block sizes.

 

Once you have figured out what sizes you want and have set the fuse values accordingly, forget about block sizes and continue.

 

The mega4809 has 1 page buffer, which is 128 bytes in size. When you write to the flash (via data space address), you are actually writing to the page buffer. The data space address you use only needs the lowest 7 bits to determine where in the page buffer the byte will go (0-127). The whole write address value ends up in the ADDR register, so that when your last write is done the ADDR will determine which page to program when the nvmctrl command is given to write flash (page buffer -> flash page).

 

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


2)about SPMCSR/SPMCR

This register doesn't exist any more in mega4809.

But the definitions still exist in boot.h:

 

/* Check for SPM Control Register in processor. */

#if defined (SPMCSR)

#  define __SPM_REG    SPMCSR

#else

#  if defined (SPMCR)

#    define __SPM_REG    SPMCR

#  else

#    error AVR processor does not provide bootloader support!

#  endif

#endif 

 

It looks like the functions in boot.h are all based on SPMCR register ,they need the definitions:

 

/* Store Program Memory Control Register - SPMCSR, SPMCR */

#define    SPMIE        7

#define    RWWSB        6

#define    RWWSRE       4

#define    BLBSET       3

#define    PGWRT        2

#define    PGERS        1

#define    SPMEN        0

 

 

I don't know if there is other updated guides for latest chips(atmega4809 and so on).

Any sample code based on NVMCTRL APPEND BOOTEND CPU.CCP ?

Maybe I need to study MuxTO firmware, it has already worked successfully.

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


Xiao wrote:

I don't know if there is other updated guides for latest chips(atmega4809 and so on).

Any sample code based on NVMCTRL APPEND BOOTEND CPU.CCP ?

It has been discussed here before.

A quick scan seems that starting with Optiboot is the key.

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

Use the Atmel START create the skeleton : select device:mega4809 -> select driver : Flash/USART/Timer.

You will get basic driver for Flash/USART, then build the top logic for bootloader.

Maybe it is time to update AVR109 & AVR911.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Optiboot was modified to support the mega0 and xTiny chips.  https://github.com/Optiboot/opti...
it’s a separate C file optiboot_x.c

the new nvm system is pretty nice, and optiboot_x comes out “significantly” shorter than the normal optiboot.

(Note that the actual arduino boards with 4809 do not use a bootloader.  They incorporate a updi programmer in the usb/serial chip.)

 

Last Edited: Sat. Nov 20, 2021 - 12:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe it is time to update AVR109 & AVR911.

Its probably time to just start fresh and target the new series of avr0/1/etc, instead of trying to make new conform to old. The only advantage to using the old is the existing pc app side, but pc app side is not difficult to create.

 

an example (not fully documented here, just pulled a few files and put them into compiler explorer)-

https://godbolt.org/z/sP79Pz67P

 

This is a bootloader for any avr0/1 in which the bootloader has very little brains. All the thinking happens on the pc side- the bootloader simply reads/sends bytes requested, or writes bytes as requested. On the pc side, there is a simple exe/bin that has a simple interface/protocol (basically send /receive bytes from a serial port via simple commands), and also has a lua interpreter built in. The pc app can be compiled for win/osx/linux, and one can use whatever scripting language preferred to interact with the pc app, or can simply use the builtin lua interpreter by giving it a script to execute. So the pc app that talks to the serial port is also somewhat dumb and the higher level scripting will be the brains (any language that can call an exe/bin, which pretty much any can do).

 

The bootloader also takes advantage of the fractional capabilities of the uart, so it also does a simple autobaud at the start of every 'packet'. It seems to work well, and I can do 500kbaud using a clock of 8 or 10mhz (cpu clock div2 chosen so will be valid for 3.3v). I have also put mcu info in a known location so the pc app side has no need to keep its own list of mcu info (page sizes,flash size, etc) so there is no need to keep updating an mcu list. The flash write function is also in a known location so can be called from mcu app space if wanted. The compiled size is <512 bytes.

 

So unless you have legacy requirements, why not treat the new avr series as something new and create something better suited.

 

 

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

That is really compact.

But I have to write in my way, for I need to provide this to my users of  game system.

Maybe we need to update appcode & eeprom。

 

How to debug the bootloader with simulator? 

Any simple and straightforward guides? I know we can do this in Atmel studio. 

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

Xiao wrote:
How to debug the bootloader with simulator? 
In exactly the way you would debug/simulate any other program . I believe the simulator will simulate SPM. ISTR the one thing it may not do is limit SPM operation to only the bootloader (so it will work in any location).

 

But for something so "chip based" isn't it better to develop it in real silicon? I believe there's a 4809 based "curiosity" board (in fact I think there was a thread from someone in Microchip marketing giving a discount code for it the other day). If you use tht it has a debugger so you can step the flash writing code as it actually does it in the real chip. When I have worked on bootloaders in the past I've always used a real chip and debugger.

 

EDIT: yeah this is the board I was thinking of: https://www.microchip.com/en-us/...

Last Edited: Mon. Nov 22, 2021 - 12:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks.

I mean I hope to feed the USART of 4809 with data, so can I debug in step.

I remember that some tools can feed target with data stored in file, but I never do it before.

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

 

@curtvm:

How to define the segment name in the ATMEL studio?

It just gives a example of boot :   .boot=0xFF

for my case,I want to divide falsh into 3 sections: bootloader 4K,appcode 34K,appdata 10K.

In created codes by START, there is a line related to section definition:

#define BOOTLOADER_SECTION __attribute__((section(".bootloader")))

Do we need to define APPCODE & APPDATA section in linker? 

is this configuration right?

 

What is the name for each section which linker knows?

 

Thank you. 

 

Last Edited: Tue. Nov 23, 2021 - 09:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A  bootloader should just be a "normal" program but in which the base of .text is (possibly) moved to a non-0 location. However, in the case of these new style AVRs I believe the bootloader comes first, not last, and is located at 0 so there should not actually be anything required at all! (having said that the one thing that probably does need to move to a non-0 location is the application you will deliver/program using the bootloader, as usual look at using -Ttext= for that).

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

The section order in flash for 4809: bootloader,appcode,appdata.

But any way we should tell studio where should it burn bootloader programme.

There is FUSE.BOOTEND & FUSE.APPEND in device programming interface of Atmel studio, these 2 FUSE actually divide whole flash into 3 sections.

We should tell linker where this bootloader should be put.

The code like this finish the job?

 

#define BOOTLOADER_SECTION __attribute__((section(".bootloader")))

 

That was defined in nvmctrl_basic.h(created by START).

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

Xiao wrote:

#define BOOTLOADER_SECTION __attribute__((section(".bootloader")))

You haven't read the "Bootloader FAQ" in the Tutorial Forum have you?

 

One point I made quite strongly in that is that the BOOTLOADER_SECTION macro from avr/boot.h has NOTHING to do with writing bootloaders. It is simply something you can use selected functions in a "normal" application program (that are involved in SPM) that will lift them away from most of the code so they can be relocated into the bootloader section (aka "BLS") so that SPM will work. This has nothing to do with writing a bootloader - it's for apps that include some SPM. While it's true the name of the macro is descriptive (it does, indeed, move things to the BLS) it's also highly misleading as people see the word "BOOTLOADER" in there and think this is how you go about writing a bootloader - it isn't.

 

The way you write a bootloader is you write a completely normal program that happens to do SPM. In the case of old style mega AVR chips you then had to arrange for this to be moved to a high address (in the BLS in fact!) and you would do this with a single -Ttext=0xnnnn to move the entire code to some base address other than the default 0.

 

However, like I say, these newer Xmega derivative chips are not like that (in fact they are not even like Xmega - which also have a "high" BLS) in that they lay out flash as boot, appcode, data from 0 up. So in this case the bootloader will be an entirely normal program - nothing has to be done to reposition it to a higher address. It should live at 0 (and that happens by default anyway). Like I said above the thing that will change for these chips is that the APPCODE cannot locate at 0 any more - it will need to be lifted a above the area set aside for the bootloader and for this you will need to employ a -Wl,-Ttext=0xnnnn to move it up to the 0xnnnn base address.

 

EDIT: bootloader FAQ: https://www.avrfreaks.net/forum/... (but remember this was written for tiny/mega so not everything will necessarily be relevant to AVR-0/AVR--1/AVR-Dx) - see point 5 for the info I added about BOOTLOADER_SECTION

Last Edited: Tue. Nov 23, 2021 - 10:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

for my case,I want to divide falsh into 3 sections: bootloader 4K,appcode 34K,appdata 10K.

boot - 0-4095

appcode - 4096 - 38911

appdata - 38912 - 49151

 

FUSES = {

    //whatever
    .WDTCFG = 0x00, // WDTCFG {PERIOD=OFF, WINDOW=OFF}
    .BODCFG = 0x00, // BODCFG {SLEEP=DIS, ACTIVE=DIS, SAMPFREQ=1KHZ, LVL=BODLEVEL0}
    .OSCCFG = 0x7E, // OSCCFG {FREQSEL=20MHZ, OSCLOCK=CLEAR}
    .SYSCFG0 = 0xF6, // SYSCFG0 {EESAVE=CLEAR, RSTPINCFG=GPIO, CRCSRC=NOCRC}
    .SYSCFG1 = 0xFF, // SYSCFG1 {SUT=64MS}

    //

    .APPEND = 0x98, // APPEND - 38912/256=152, 4096 - 38911
    .BOOTEND = 0x08, // BOOTEND - 4096/256=8, 0 - 4095

    .BOOTEND = 0x10, // BOOTEND - 4096/256=16, 0 - 4095

    //APPDATA = 38912 - 49152

};

 

Your bootloader can be built as a normal app, just need watch the size to stay <4k. Your apps will need to be built with .text moved up to 4096/0x1000, since that is where they will live in flash.

 

Last Edited: Wed. Nov 24, 2021 - 08:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did not read the QA, it is helpful,thank you.

We don't do special work for bootloader indeed, the default .text starts from 0x0.

 

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

OK, so what I should do:

1)keep code size for bootloader less than 4K;

2)set FUSE .APPEND=0x98 .BOOTEND=0x10 while burning bootloader;

3)set .text=(0x1000>>1) for AVR/GNU linker in toolchain configure interface while building application. 

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

2) yes, 0x10 is the correct value (not 0x08 as I said, it seems I cannot do division or run a calculator- I hope to improve).

 

3) if you provide the option, use the byte address-

-Wl,--section-start=.text=0x1000

if you use the gui to set the .text section (in MPLABX anyway), they seem to consider that value a word address for some reason and 'convert' it to a byte address- it will still show as the same generated command line in the ld options, but somewhere in the process they convert the value if its set in the gui.

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

For I have no hardware to debug,I hope to debug with stimuli file.

We need to feed USART.RXDATAL with data.

According to simulator guide,I tried with name and address directly, but the code not run as I thought,it still thinks there is no data received:

 

stimuli file:

#10
$log USART3.TXDATAL

$log USART3.RXDATAL
//$log USART3.STATUS
$startlog 4809boot_log_output.stim
//USART3.STATUS = 0x20
#13000
USART3.RXDATAL = 0x63

#100
0x860 = 0x64
#10
$log USART3.STATUS
#400000
$stoplog
$break
$quit 

log file:

#80
USART3.TXDATAL = 0x57
#21
USART3.TXDATAL = 0x69
#21
USART3.TXDATAL = 0x6c
#4141
USART3.TXDATAL = 0x64
#4171
USART3.TXDATAL = 0x0a
#4166
USART3.TXDATAL = 0x0d  
#4160
USART3.STATUS = 0x20
#8335
USART3.STATUS = 0x60

I tried to feed RXDATAL  : 0x860 = 0x63

but as log showed, this sentence was not logged,that means it is illegal.

It will be impossible to debug bootloader if we can't feed value to RX port.

Anyone know about it?

 

Last Edited: Wed. Nov 24, 2021 - 08:48 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,you are right.

We need input word address in Atmel Studio(7.0).

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

Improved the stimuli commands:

#10
$log USART3.TXDATAL
$log USART3.RXDATAL
$log USART3.STATUS
$startlog 4809boot_log_output.stim
//USART3.STATUS = 0x20
#13000
USART3.RXDATAL = 0x63
#100
0x860 = 0x64
#10
//$log USART3.STATUS
#400000
$stoplog
$break
$quit

The log is same, no RXDATAL data logged.

 #1
USART3.STATUS = 0x20
#79
USART3.TXDATAL = 0x57
#21
USART3.TXDATAL = 0x69
#21
USART3.TXDATAL = 0x6c
#1
USART3.STATUS = 0x00
#4134
USART3.STATUS = 0x20
#6
USART3.TXDATAL = 0x64
#1
USART3.STATUS = 0x00
#4161
USART3.STATUS = 0x20
#9
USART3.TXDATAL = 0x0a
#1
USART3.STATUS = 0x00
#4157
USART3.STATUS = 0x20
#8
USART3.TXDATAL = 0x0d
#1
USART3.STATUS = 0x00
#4159
USART3.STATUS = 0x20
#8335
USART3.STATUS = 0x60

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

Forget Stimuli for something like this - just get a debugger. Curiosity Nano 4809 is about £13 and there was a discount code on that posted here in the last month. It is a 4809 but with a fully fledged debugger attached. Personally I wouldn't think of trying to develop a bootloader without having access to a debugger and real silicon.

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

laugh

I get your meaning.

But,I will give up supporting arduino.

So ATSAMD11 will be removed,replaced with USB to USART bridge chip.

I have to build a bootloader for upgrade operation late by user.

Hardware redesign on the way,I just want to do something in advance.