Сергей Борщ, ОГРОМНОЕ спасибо за советы и за Ваш линкер-скрипт. Буду разбираться с ним.
По поводу моей проблемы: я изменил функцию записи во флеш на ту, которую предлагали Вы в многочисленных аналогичных обсуждениях, ибо она прекрасна:
Код
#define RAMFUNC __attribute__ ((section (".ramfunc")))
void RAMFUNC FlashTest_RAM(uint32_t command)
{
AT91C_BASE_MC->MC_FCR = command;
//AT91C_BASE_PIOA->PIO_SODR = 0x400; // Тут необъяснимое явление. Кстати 0х400 - это 10ый PIO, к нему подключен светодиод.
while(!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
}
void FlashTest(uint32_t command, uint32_t mode)
{
AT91F_Disable_Interrupt();
AT91C_BASE_MC->MC_FMR = mode;
FlashTest_RAM(command);
AT91F_Enable_Interrupt();
}
#define MCK_CYCLES ((15ULL * MCK + 5000000) / 10000000)
#define FLASH_WAITSTATES MCK_CYCLES < 30000000ULL ? AT91C_MC_FWS_0FWS : AT91C_MC_FWS_1FWS
inline void RewritePage(uint32_t const *addr)
{
FlashTest( (0x5AULL * AT91C_MC_KEY / 0xFF) | (((uint32_t)addr >> 7) << 8) | AT91C_MC_FCMD_START_PROG, \
(0 * AT91C_MC_FRDY) | (0 * AT91C_MC_LOCKE) | ( 0 * AT91C_MC_PROGE) | (0 * AT91C_MC_NEBP) | (FLASH_WAITSTATES) | (MCK_CYCLES * AT91C_MC_FMCN / 0xFF));
}
Процессор точно так же зависал, НО!!! Если разкоментировать строчку AT91C_BASE_PIOA->PIO_SODR = 0x400, которую я пометил как "необъяснимое явление", то все прекрасно работает!!! Т.е. если зажечь в этом месте светодиод, то все работает!!! Вопрос - Как так-то?!
Кстати пользуясь случаем, хочу задать Вам вопрос по функции записи, а вернее по данному элементу: (((uint32_t)addr >> 7) << 8). Зачем смещать на 7? Я этого никак понять не могу... И какой в этом случае формат адреса страницы addr?
Я изменил на ((uint32_t)addr << 8) и когда, например, обращаюсь к 512ой странице, присваиваю addr = 0x200. Работает и это меня не удивляет.