ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
4 декабря
142474 Топик полностью
Ксения (17.12.2008 02:42, просмотров: 370) ответил бомжнаработе на Из Application section писать в Boot section нельзя. Но в EEPROM можно. А позже передать управление в бут и что-то изменить в Application. Но это извращение.
Поднялась в 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. Вот вроде бы и всё. Где здесь я могла ошибиться, ума не приложу. Еще сильнее ужимать код, чтобы локализовать ошибку, я больше не могу.