Поднялась в BOOT-область, но инструкция SPM всё равно не работает. Взяла самый простой случай - стереть начальную страницу flash-памяти. Короче написать уже невозможно.
Привожу листиг компилятора:
#define _WAIT_FOR_SPM() while( SPMCSR & (1<<SPMEN));
#define _PAGE_ERASE(addr) __AddrToZByteToSPMCR_SPM( (void __flash *) (addr), 0x03 )
1420 #pragma location="BOOT"
1421
In segment BOOT, align 2, keep-with-next
1422 void Eraser()
\ Eraser:
\ ??Eraser_0:
1423 {
1424 _WAIT_FOR_SPM();
\ 00000000 B707 IN R16, 0x37
\ 00000002 2F10 MOV R17, R16
\ 00000004 FD10 SBRC R17, 0
\ 00000006 CFFC RJMP ??Eraser_0
1425 _PAGE_ERASE( 0);
\ 00000008 E003 LDI R16, 3
\ 0000000A E0E0 LDI R30, 0
\ 0000000C E0F0 LDI R31, 0
\ 0000000E BF07 OUT 0x37, R16
\ 00000010 95E8 SPM
1426 }
\ 00000012 9508 RET
_WAIT_FOR_SPM() ждет окончания предыдущей операции - исчезновение бита SPMEN в регистре SPMCSR. Эту часть можно безболезненно удалить, т.к. у меня это единственная операция с SPM. Однако я ее добавила, чтобы не было формальных нареканий.
_PAGE_ERASE( 0) - собственно это и должно стирать страницу. R31:R30 - адрес страницы. Специально выбрала 0, чтобы исключить нарекания в том, что я неправильно рассчитала ее адрес. Ноль он и в Африке ноль, как в байтах, так и в словах. А кроме того, стирание стартовой части flash-памяти не должно пройти незамеченным.
0x37 - номер регистра SPMCSR в моем AT90USB647, согласно даташита. Это обычный стандарт для этого регистра, хотя у ATmega64 этот регистр находится в другом месте (в памяти) и адресуется по-другому.
Тройка, которая сначала грузится в R16, а потом загружаться в SPMCSR, это биты PGWRT и SPMEN.
А вот еще доказательство, что моя BOOT-область расположена выше адреса 7E00 - выдержка из MAP:
BOOT
Relative segment, address: CODE 00007E00 - 00007E13 (0x14 bytes), align: 1
Segment part 268.
ENTRY ADDRESS REF BY
===== ======= ======
Eraser 00007E00
stack 1 = 00000000 ( 00000002 )
7E00 - это начало самой высокой BOOT-области, которую только можно получить фузами BOOTSZ. Т.е. при любых фузах это будет областью BOOT. А на моем значении BOOTSZ=1 начало BOOT-области еще ниже - 7800.
Вот вроде бы и всё. Где здесь я могла ошибиться, ума не приложу. Еще сильнее ужимать код, чтобы локализовать ошибку, я больше не могу.
-
- По-моему в МАР у Вас адрес указан в байтах, а не в словах. До boot-области - не дотянули... - Палыч(17.12.2008 09:51)
- Вау!!! - Ксения(17.12.2008 14:02)
- По-моему в МАР у Вас адрес указан в байтах, а не в словах. До boot-области - не дотянули... - Палыч(17.12.2008 09:51)