Цитата(_Артём_ @ Nov 11 2012, 18:11)

Да, обязательно нужно чтобы функция пишущия флеш находилать в области бута.
Код может быть 4кБ.
Некоторую часть программы можно вынести в application section.
Сделать это можно например так:
1. Создать сегмент в application section.
Нужно либо редактировать xcl или в свойствах проекта - Linker - вкладка Extra options добавить что-то такое(адреса выбраны ):
Код
-Z(CODE)FUNC_SEGMENT=7F00-7FFF
2. Расположить функции в сегменте FUNC_SEGMENT
Код
unsigned char GetPin() @ "FUNC_SEGMENT"
{
return PORTA.IN;
}
спасибо за поддержку!
Нашел документ от атмел AVR106 в котором есть пример как переносить функции самопрограммирования в область бута, изменил xcl вот что получается:
Код
/* - lnkxm32d4s.xcl -
*
* XLINK command file for the ICCAVR C-compiler using the --cpu=xm32d4, -ms
* options. Segments are defined for an ATxmega32D4.
*
* Usage: xlink your_file(s) -f lnkxm32d4s
*
* File version: $Revision$
*/
/*====================================================*/
/*
* Constants used down below,
* Do not change these lines,
* if it is not stated otherwise
*/
/* Code (flash) segments */
-D_..X_INTVEC_SIZE=16C /* 4 bytes * 91 vectors */
-D_..X_APPLICATION_SIZE=8000
-D_..X_BOOT_SIZE=1000
-D_..X_APPLICATION_TABLE_SIZE=1000
-D_..X_FLASH_END=(_..X_APPLICATION_SIZE+_..X_BOOT_SIZE-1)
-D_..X_APPLICATION_START=_..X_INTVEC_SIZE
-D_..X_APPLICATION_END=(_..X_FLASH_END-_..X_BOOT_SIZE-_..X_APPLICATION_TABLE_SIZE)
-D_..X_APPLICATION_TABLE_START=(_..X_APPLICATION_END+1)
-D_..X_APPLICATION_TABLE_END=(_..X_FLASH_END-_..X_BOOT_SIZE)
-D_..X_BOOT_START=(_..X_APPLICATION_TABLE_END+1+X_INTVEC_SIZE)
-D_..X_BOOT_END=_..X_FLASH_END
-D_..X_FLASH_NEND=_..X_FLASH_END /* End of near flash memory */
-Z(FARCODE)BOOT_SEGMENT=(_..X_FLASH_END-_..X_BOOT_SIZE+1)-_..X_FLASH_END
/* Internal data memory */
-D_..X_SRAM_BASE=2000 /* Start of ram memory */
-D_..X_SRAM_END=2FFF /* End of ram memory */
-D_..X_SRAM_TBASE=0 /* Start of tiny ram memory */
-D_..X_SRAM_TSIZE=0 /* Size of the tiny ram memory */
/* Internal EEPROM */
-D_..X_EEPROM_START=0
-D_..X_EEPROM_END=3FF /* End of eeprom memory */
/*====================================================*/
/*
* Modify the lines below to alter the size of the RSTACK, CSTACK and HEAP
* segments. These need to be fine tuned to suit your specific application.
* The '_..X_' prefix is used by C-SPY as an indication that the label should
* not be displayed in the dissassembly window.
*/
//-D_..X_CSTACK_SIZE=200 /* 512 bytes for auto variables and saved registers. */
//-D_..X_RSTACK_SIZE=40 /* 64 bytes for return addresses, equivalent to 32 */
/* levels of calls, including interrupts. */
//-D_..X_HEAP_SIZE=100 /* 256 bytes of heap. */
//-D_..X_NEAR_HEAP_SIZE=100 /* 256 bytes of heap. */
/*
* The following segments are located in the internal memory of
* the ATxmega32D4. Do not change these lines.
*/
/* Define CPU */
-ca90
/* Code memory */
//-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)
-Z(CODE)INTVEC=8000-81F4
/* Fill unused interrupt vector's with RETI */
//-H1895
-h(CODE)0-_..X_INTVEC_SIZE
//-D_..X_FLASH_BASE=_..X_INTVEC_SIZE
-Z(CODE)NEAR_F=_..X_FLASH_BASE-_..X_FLASH_NEND
-Z(CODE)SWITCH=_..X_FLASH_BASE-_..X_FLASH_NEND
-Z(CODE)DIFUNCT=_..X_FLASH_BASE-_..X_FLASH_NEND
-Z(CODE)CODE=_..X_FLASH_BASE-_..X_FLASH_END
-Z(CODE)INITTAB=_..X_FLASH_BASE-_..X_FLASH_END
-Z(CODE)TINY_ID=_..X_FLASH_BASE-_..X_FLASH_END
-Z(CODE)NEAR_ID=_..X_FLASH_BASE-_..X_FLASH_END
-Z(CODE)APPLICATION=_..X_FLASH_BASE-_..X_APPLICATION_END
-Z(CODE)APPLICATION_TABLE=_..X_APPLICATION_TABLE_START-_..X_APPLICATION_TABLE_END
-Z(CODE)BOOT=_..X_BOOT_START-_..X_BOOT_END
-Z(CODE)CHECKSUM#_..X_FLASH_END
/* Internal data memory */
-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE
-Z(DATA)NEAR_I,NEAR_Z,NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)IOSTREAM_N#_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
/* Internal eeprom memory */
-Z(XDATA)EEPROM_I,EEPROM_N=_..X_EEPROM_START-_..X_EEPROM_END
// The compiler and linker now automatically includes the smallest set of
// run-time library string formatting support possible for functions such as
// printf/scanf, based on which formatters that are actually used in the
// application. To revert to the old behavior of specifying the level of
// support manually, the default linker files needs to be modified. Please
// see comments inside the linker files for more information on which
// modifications that are needed.
//
// /* Select reduced "printf" support to reduce library size.
// See configuration section in manual concerning printf/sprintf. */
//
// /*Dlib*/
// -e_PrintfSmall=_Printf
//
// /*Clib*/
// -e_small_write=_formatted_write
//
// /*Dlib and Clib*/
// -e_small_write_P=_formatted_write_P
//
// /* Disable floating-point support in "scanf" to reduce library size.
// See configuration section in manual concerning scanf/sscanf */
//
// /*Dlib*/
// -e_ScanfSmall=_Scanf
//
// /*Clib*/
// -e_medium_read=_formatted_read
//
// /*Dlib and Clib*/
// -e_medium_read_P=_formatted_read_P
/* Suppress one warning which is not relevant for this processor */
-w29
/* Code will now reside in file aout.a90 or aout.d90, unless -o is specified */
/* .d90 is the default if debug system is linked (option -r) */
/* .a90 is the default without debugging. Default format is -Fmotorola */
описание и функций
Код
#pragma vector = NVM_SPM_vect
__interrupt void NVM_SPM_vectint(void) @ "BOOT_SEGMENT"
{
// Disable the SPM interrupt
NVM.INTCTRL = (NVM.INTCTRL & ~NVM_SPMLVL_gm);
// Restore sleep settings
SLEEP.CTRL = sleepCtr;
// Restore PMIC status and control registers
PMIC.STATUS = statusStore;
PMIC.CTRL = pmicStore;
// Restore SPM interruptsettings
NVM.INTCTRL = spmintStore;
// Restore global interrupt settings
SREG = globalInt;
//return;
}
/* Temporary storage used for NVM-workaround. */
/* Set interrupt vector location to boot section of flash */
__root void PMIC_SetVectorLocationToBoot( void ) @ "BOOT_SEGMENT"
{
uint8_t temp = PMIC.CTRL | PMIC_IVSEL_bm;
CCP = CCP_IOREG_gc;
PMIC.CTRL = temp;
}
/*Set interrupt vector location to application section of flash */
__root void PMIC_SetVectorLocationToApplication( void ) @ "BOOT_SEGMENT" {
uint8_t temp = PMIC.CTRL & ~PMIC_IVSEL_bm;
CCP = CCP_IOREG_gc;
PMIC.CTRL = temp;
}
/* Save register settings before entering sleep mode */
__root void Prepare_to_Sleep( void ) @ "BOOT_SEGMENT"
{
sleepCtr = SLEEP.CTRL;
// Set sleep mode to IDLE
SLEEP.CTRL = 0x00;
// Save the PMIC Status and control registers
statusStore = PMIC.STATUS;
pmicStore = PMIC.CTRL;
// Enable only the highest level of interrupts
PMIC.CTRL = (PMIC.CTRL & ~(PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm)) | PMIC_HILVLEN_bm;
// Save SREG for later use
globalInt = SREG;
//Enable global interrupts
sei();
// Save SPM interrupt settings for later
spmintStore = NVM.INTCTRL;
}
/* New function declarations used for the NVM-workaround */
__root void EraseApplicationPage(uint32_t address) @ "BOOT_SEGMENT"
{
//Set the correct settings and store critical registers before NVM-workaround
Prepare_to_Sleep();
//Assembly "function" to preform page erase
SP_EraseApplicationPage(address);
}
__root void EraseWriteApplicationPage(uint32_t address) @ "BOOT_SEGMENT"
{
//Set the correct settings and store critical registers before NVM-workaround
Prepare_to_Sleep();
//Assembly "function" to preform page erase-write
SP_EraseWriteApplicationPage(address);
}
__root void ClearFlashBuffer(void) @ "BOOT_SEGMENT"
{
//Set the correct settings and store critical registers before NVM-workaround
Prepare_to_Sleep();
//Assembly "function" to erase flash buffer
SP_EraseFlashBuffer();
}
__root void LoadFlashWord(uint32_t address, uint16_t word) @ "BOOT_SEGMENT"
{
//Set the correct settings and store critical registers before NVM-workaround
Prepare_to_Sleep();
//Assembly "function" to load flash buffer
SP_LoadFlashWord(address, word);
}
__root void flashex() @ "BOOT_SEGMENT"
{
PMIC_SetVectorLocationToBoot();
//PMIC_SetVectorLocationToApplication( );
ClearFlashBuffer();
for(y=0;y<(128);y+=2)
{ //
//flashdata[y]=0x55;
LoadFlashWord(y,0xAAAA);
SP_WaitForSPM();
}
EraseWriteApplicationPage(16000);
//SP_LoadFlashPage(flashdata);
// SP_EraseWriteApplicationPage(0x3E);
//PORTD_OUT |= 0x40;
if(SP_ReadByte(0x3E00)==0xAA)
{
PORTD_OUT |= 0x40;
}
}
вызываю
Код
flashex();
Тем самым пытаюсь сделать наоборот - вытаскивать код записи во влеш в область бута
Результат, по адресу 8000 есть вставка кода но есть ли там прерывания не могу сказать, в итоге самой записи нет(((((......