Навеяло тако алгоритм: - при линковке выделяем пустой регион где-нибудь в конце рамы; - при запуске в симуляторе разрешаем исполнять с региона (map addr_start, addr_end read write exec) - после входа в майн (у меня там сразу вызывается void Init(void)) первым делом копируем тела нужных прерываний в заготовленную область, начало - имя функции (новый адрес пишем в массив для посл. использования при инициализщации прерываний), конец - конструкция SUBS PC,R14,0x00000004, или 0xE25EF004 после ассемблера, - при настройке прерываний указываем не адрес функции, написанной во флеш, а адрес ее копии из массива.
По идее, должно работать как часы. А вот нифига. Проверял только в симуляторе - железа под рукой нет и будет еще не скоро. Мучал прерывание по сравнению таймера 0. При использовании родных функций (не копий) все работает как надо - вход в прерывание = (сохранение регистров), выход - восстановление PC как R13 - 4, дальше продолжаем с прерванного места. При использовании копии происходит следующее: - копирование: все в норме. Смотрю регионы памяти - байт в байт, хвост не пропустил, длины совпадают. - инициализация: все в норме. Прерывание заносится в АИЦ без малейших вопросов. - генерация прерываний: переход на 0x18 (IRQ), оттуда прыжок на копию функции. - в функции: выполняются все запрограммированные действия (получение и маскирование флагов прерывания, проверка каждого флага, запись 0 в EOICR). - дошли до возврата. Смотрю R13 = 0x20061C (основной цикл в майн - оттуда ушли в прерывание), в PC заносится 0x200618 = R13 - 4. Все круто! Работает. Но вот только почему-то, блин, переход происходит не на 0x200618, а снова на 0x18! Почему? Есл кто знает, видел, читал, объясните, пожалуйста, а то два вечера уже ковыряю. Идей никаких. PS Читаю про RELOC опцию региона... Может, оно самое?
|