Работаю в IAR AVR v3.20. Для указания адреса, по которому нужно расположить код функции, необходимо использовать директиву
#pragma location = "CODE_BOOT"
где CODE_BOOT - системная константа, которая задаётся в пункте меню Project/Options/XLINL/Extra Options. Там в окошечке нужно записать следующую строку
-Z(CODE)CODE_BOOT=хххх-уууу
где хххх и уууу - адреса начала и конца области памяти начального загрузчика (шестнадцатеричные). Код функции будет расположен по адресу хххх.
Для более ранних версий компиляторов в меню необходимого окошка может не оказаться. Тогда надо ключевую строку записывать в коммандной строке вызова компилятора (такой методом не пользовался).
Вот функция, которая предназначена для программирования памяти контроллера:
#pragma location = "CODE_BOOT"
void write_flash_page(unsigned int Addr_w, unsigned char *flash_buffer)
{
unsigned char ii_w;
unsigned int data_w;
_Wait_SPMEN;
_SPM_ERASE(Addr_w);
_Wait_SPMEN;
_Enable_RWW;
for (ii_w=0; ii_w ‹ 64; ii_w++)
{
data_w=(*(flash_buffer+ii_w*2))+((*(flash_buffer+i i_w*2+1))‹‹
![Горд собой](images/smilies/icon_dovl.gif)
;
_Wait_SPMEN;
_SPM_FILLTEMP(Addr_w, data_w);
Addr_w+=2;
}
Addr_w-=128;
_Wait_SPMEN;
_SPM_PAGEWRITE(Addr_w);
_Wait_SPMEN;
_Enable_RWW;
}
Перед вызовом этой функции необходимо считать участок перезаписываемой памяти другой функцией в буфер:
void read_flash_page(unsigned int Addr_r, unsigned char *flash_buffer)
{
unsigned char ii_r;
for (ii_r=0; ii_r ‹ 128; ii_r++)
{
*(flash_buffer+ii_r)=_LPM((unsigned char const __flash *)Addr_r);
Addr_r++;
}
}
Главное, необходимо помнить, что память меги разбита на страницы и начальный адрес считывания и записи должен быть кратен величине этой страницы, иначе результат операции не предсказуем.