Xmega 256A3BU self programming.

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

Hello everyone,

 

I'm working on atxmega256A3BU self programming.

It is a custom board and i have already written the content of .bin file in my memory location.

i tried to write into the application section, but the device is booting into the previous code.

when i tried to print AFM content i found out that i'm not overwriting the content of AFM.

 

I'm using SP_driver.h, 

F_CPU = 2000000UL

 

for the first time when i'm flashing bootloader using jtag ice from atmel studio ...the setting are as:

 

Bootrst: application

Fusebyte0: 0xFF

Fusebyte1: 0xFF

Fusebyte2: 0xFF

Fusebyte4: 0xFF

Fusebyte5: 0xFF

 

Bootrst: bootloader

Fusebyte0: 0xFF

Fusebyte1: 0xFF

Fusebyte2: 0xBF

Fusebyte4: 0xFF

Fusebyte5: 0xFF

 

have written the following in linker:  --section-start=.boot=0x40000

 

the code is as follows:

 

void self_reprogramming(void)
{
OSC.CTRL |= OSC_RC2MEN_bm;
while(!(OSC.STATUS & OSC_RC2MRDY_bm));
DFLLRC2M.CTRL = DFLL_ENABLE_bm;
    
PMIC.CTRL = PMIC_IVSEL_bm | PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm;
    
if(NVM.CTRLB & NVM_SPMLOCK_bm) {
    CCP=0;
    }
    
    for (int xx=0; xx < 500; xx++ )
	{
		for (int yy=0; yy < SPM_PAGESIZE; yy++ )
		{
			buffer_fota[yy]= 0xFF;
		}
		flash_read(ufs_file_read,512,&buffer_fota[0]);	//	copy the data from flash to buffer
		user_debug_1("\r\nFTP_flash_read: ");
		user_debug_1("\r\n%s",buffer_fota);
		user_debug_1("\r\n");
		
		Flash_ProgramPage(page_location, buffer_fota, 1);
		
		SP_ReadFlashPage(&Read_fota,page_location );
		user_debug_1("\r\nAFM_flash_read: ");
		user_debug_1("\r\n%s",Read_fota);
		user_debug_1("\r\n");
		
		page_location = page_location + 512;
		ufs_file_read = ufs_file_read + 512;
	}
}


void Flash_ProgramPage(uint32_t page, uint8_t *buf, uint8_t erase)
{
	
	if (erase)
	{
		SP_EraseApplicationPage(page);
		SP_WaitForSPM();
		SP_LoadFlashPage(buf);
		SP_WaitForSPM();
		SP_WriteApplicationPage(page);
		SP_WaitForSPM();
		SP_EraseFlashBuffer();
	}
	else
	{
		SP_WriteApplicationPage(page);
	}
	SP_WaitForSPM();
}

can anyone help me with this...?

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

Mehul9 wrote:
have written the following in linker:  --section-start=.boot=0x40000
Sorry but where is ".boot" used in any of that code you have shown? Surely you mean " --section-start=.text=0x40000 "? It is the text of the program you are building that you want at location 0x40000.

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

Thanks Clawson,

 

I  exactly don't know this linker is doing, i have tried both .boot and .text  and waited for the best.

 

before writing into application section from memory what are steps i'm missing?

and also what this linker thing is doing?.... 

#define PROGMEM_START     (0x0000)
#define PROGMEM_SIZE      (270336)
#define PROGMEM_END       (PROGMEM_START + PROGMEM_SIZE - 1)

#define APP_SECTION_START     (0x0000)
#define APP_SECTION_SIZE      (262144)
#define APP_SECTION_PAGE_SIZE (512)
#define APP_SECTION_END       (APP_SECTION_START + APP_SECTION_SIZE - 1)

#define APPTABLE_SECTION_START     (0x3E000)
#define APPTABLE_SECTION_SIZE      (8192)
#define APPTABLE_SECTION_PAGE_SIZE (512)
#define APPTABLE_SECTION_END       (APPTABLE_SECTION_START + APPTABLE_SECTION_SIZE - 1)

#define BOOT_SECTION_START     (0x40000)
#define BOOT_SECTION_SIZE      (8192)
#define BOOT_SECTION_PAGE_SIZE (512)
#define BOOT_SECTION_END       (BOOT_SECTION_START + BOOT_SECTION_SIZE - 1)

 

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

The key thing about bootloaders is putting the code that does the SPM in the location where SPM can execute. As long as the code is moved to the 8K above 256K then it should work OK there.

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

The main problem i'm facing is that I don't know how to put the spm command into the boot section so they can be executed as for now all this code is sitting in my application section.

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

The .text=0x40000 thing should do it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
.section .text		
.global SP_WriteApplicationPage

SP_WriteApplicationPage:
	in	r19, RAMPZ                       ; Save RAMPZ, which is restored in SP_CommonSPM.
	out	RAMPZ, r24                       ; Load RAMPZ with the MSB of the address.
	movw	r24, r22                         ; Move low bytes of address to ZH:ZL from R23:R22
	ldi	r20, NVM_CMD_WRITE_APP_PAGE_gc   ; Prepare NVM command in R20.
	jmp	SP_CommonSPM                     ; Jump to common SPM code.

 

the above one is the definition of function in driver file(.s) 

.text = 0x40000 basically make this command to run in boot section 

 

 

am i right???

 

also before running spm command i have to set some lock bits...

does my code have taken care of that????

 

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

also should i use 

 

--section-start=.text=0x40000

 

?????????

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

I'm never a fan of splitting bootloader stuff between app section and  boot section. In my world an AVR may contain two distinct and separate programs. A bootloader which is complete in its own right and is positioned at the BLS address (so a fixed 0x40000 in this chip) and then the app at 0x0000. Just write your bootloader as a complete program and just use -section-start=.text=0x40000 which will move everything (which includes the SPM routines) to the upper address

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

How the whole code will reside in boot section as my file is of about 100 KB and boot section is of 8KB??

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

Oh I see, so you just want to add some flash writing to an existing algo, not write a bootloader. Sorry that was not clear to me. But I would still tag ALL the routines that will be involved in the data rewriting process (not just the SPM itself) as ".boot". In fact <avr/boot.h> contains the BOOTLOADER_SECTION macro for this very purpose.

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

I have tried .text = 0x40000 in linker but was not able to load the file 

atmel filp says  "address out of range"

 

never seen boot.h before

will look into <avr/boot.h> .... and let you know...

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

This is what works for me. I add a .boot memory section in linker settings. I then declare my bootloader related functions like this:

 

void __attribute__ ((section (".boot")))__attribute__ ((noinline)) BL_func(void)
{
    // SPM code
}

 

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

Hi balisong42,

 

thanks for reply....

I'm getting error while using <avr/boot.h>  -- Avr does not provide bootloader support

 

 

I'll just clear my exact use case:

So i already have USB DFU bootloader sitting in my boot section, which i use to program my board from atmel flip.

I want to add fota feature on it.... and also i don't want to lose the flip programming feature.

My application code .bin file is of about 100KB  

 

i don't want to create an exact bootloader, but from application code i would be able to call SPM commands which really executes and overwrites Application section.

 

firstly is this possible ??? because currently i'm executing spm commands from application section and surely it's not going to work.

 

can this function you specified can work?

void __attribute__ ((section (".boot")))__attribute__ ((noinline)) BL_func(void)
{
    // SPM code
}

 or can we create a custom/secondary bootloader in application section that really can execute spm cmd???

 

******** note: I'm using atmel flip to burn the hex file, as my jtag setup is not with me.

 

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

The point is that boot.h simply has something like:

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

so when you have:

void foo() {
    // stuff
}

void bar() {
    // stuff
}

void spm_write_data(int addr, void * data) {
    foo();
    bar();
    // stuff
}

you can just sprinkle it with:

BOOTLOADER_SECTION void foo() {
    // stuff
}

BOOTLOADER_SECTION void bar() {
    // stuff
}

BOOTLOADER_SECTION void spm_write_data(int addr, void * data) {
    foo();
    bar();
    // stuff
}

Then later on just -Wl,-section-start=.boot=0x40000

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

Thanks Clawson,

i tried this out, and had used AVR106 app note for reference.

From my main function i have simplr called, for eg: foo();   --- foo defined as bootloader_section  

 

but the problem is I'm flashing my board using atmel flip via usb, and as i load hex in flip it says "Address out of range".

also i have preloaded DFU USB bootloader

 

do i have to flash it using Jtag ICE????

Last Edited: Wed. Jul 22, 2020 - 10:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do i have to use Jtag ICE to program the board.

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

Mehul9 wrote:
but the problem is I'm flashing my board using atmel flip via usb, and as i load hex in flip it says "Address out of range".
How could that possibly work. Flip relies on "DFU" in the bootloader section of the AVR. You would be saying "DFU please over-write yourself with this new bootloader section code I am delivering". It won't do that. It's a bit like pulling the rug out from beneath your own feet!

 

So, yes, you need JTAG/PDI to put the code into the chip (and in the process you will lose DFU so Flip can no longer be used).

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

Thanks Clawson,

 

It is possible to customize the DFU bootloader ...Right?

 

i was thinking that if i would try to merge my code my code with dfu one...

mine one is just picking from flash memory and writing to application section.

 

but i have read lot of threads on 8k and 4k tight memory location ....

 

and also where can i find the source code of DFU bootloader...

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

Mehul9 wrote:
It is possible to customize the DFU bootloader ...Right?
Yes, I imagine that at its heart DFU must have some "write SPM page" routine. If you could just expose that to your app then the rest could live in the app section.

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

Mehul9 wrote:
and also where can i find the source code of DFU bootloader...
http://web.archive.org/web/20170302213231/http://www.atmel.com/Images/AVR1916.zip

 

P.S.

Mehul9 wrote:
mine one is just picking from flash memory and writing to application section.
Similar for the Serial Bootloader (external flash for OTAU store); two XMEGA in it.

AN_8390 AVR2054: SerialBootloader User Guide

XMEGA384C3 has USB and enough flash to store a few (several?) applications.

 


AN_8429 AVR1916: USB DFU Boot Loader for XMEGA

Booting from XMEGA application code into the bootloader (and staying there!) | AVR Freaks

ganzziani/Xproto-Watch-Bootloader · GitHub

ATxmega384C3 - 8-bit AVR Microcontrollers

 

"Dare to be naïve." - Buckminster Fuller