Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Wiggler
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Pat
Отлаживаюсь посредством Wiggler.
Кристал AT91SAM7S32.
Если поставить брекпоинт в прерывании, то он работает через раз, а то и через 10 раз.
Вообще, что то странное присходит. Для того что бы заработали сами прерывания иногда приходится загрузить бинарник вначале в FLASH а потом в RAM. Иногда все работает без этого шаманства.
Может кто сталкивался с этой проблемой.
Pat
Цитата(Pat @ Sep 24 2005, 22:13)
Вообще, что то странное присходит. Для того что бы заработали сами прерывания иногда приходится загрузить бинарник  вначале в FLASH а потом в RAM. Иногда все работает без этого шаманства.
Может кто сталкивался с этой проблемой.
*

Отвечу сам себе.
В EWARM IAR4.30 для загрузки RAM и FLASH в AT91SAM7xxx используются макросы SAM.mac и SAM_RAM.mac.
В них производятся некоторые процедуры инициализации перед загрузкой кристалла.
Одна из них сброс AIC (контроллер прерываний). Вот она собственно
//-------------------------------
// Normally, the code is executed only if a reset has been actually performed.
// So, the AIC initialization resumes at setting up the default vectors.
//-----------------------------------------------------------------------------
AIC()
{
// Mask All interrupt pAic->AIC_IDCR = 0xFFFFFFFF;
__writeMemory32(0xffffffff,0xFFFFF124,"Memory");
__writeMemory32(0xffffffff,0xFFFFF128,"Memory");
// disable peripheral clock Peripheral Clock Disable Register
__writeMemory32(0xffffffff,0xFFFFFC14,"Memory");

// #define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register
// #define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register
// #define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register
__readMemory32(0xFFFA0020,"Memory");
__readMemory32(0xFFFA0060,"Memory");
__readMemory32(0xFFFA00A0,"Memory");

// Ниже по тексту собственно основная проблема и живет,
// в AIC есть регистр AIC_EOICR который WRITE-ONLY и служит он для(цитирую):
// The End of Interrupt Command Register is used by the interrupt routine to indicate
// that the interrupt treatment is complete.
// Any value can be written because it is only necessary to make a write to this register
// location to signal the end of interrupt treatment.

for (__mac_i=0;__mac_i < 8; __mac_i++)
{

// Но в иаровских мак файлах почему то производится чтение из этого регистра
// __mac_pt = __readMemory32(0xFFFFF130,"Memory"); // __mac_pt = AIC_EOICR
// У меня аномальное поведение прерываний после загрузки, вылечилось
// нижней строкой
// теперь после загрузки с прерываниями все ОК
__writeMemory32(0xffffffff,0xFFFFF130,"Memory"); // AIC_EOICR = 0xFFFFFFFF
}
__message "------------------------------- AIC 2 INIT ---------------------------------------------";
}
Проблему так же можно решить, вставив в свой код функцию
сброса AIC

#include "include/AT91SAM7S32.h"
void reset_AIC(void)
//-----------------------------------------------------------------------------
// Сброс Interrupt Controller AIC
//-----------------------------------------------------------------------------
void reset_AIC(void)
{
unsigned int i;
// Отключаем все источники прерываний
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
// Очищаем все прерывания
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
// Отключаем периферию от системного клока
AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFF;
// Сбрасываем флаги таймеров
i = AT91C_BASE_TC0->TC_SR;
i = AT91C_BASE_TC1->TC_SR;
i = AT91C_BASE_TC0->TC_SR;
for (i=0;i < 8;i++)
{
// Все прерывания закончены
AT91C_BASE_AIC->AIC_EOICR = 0xFFFFFFFF;
}
}

p.s. Проблемма с работой брейк поинтов в прерываниях ИАР все равно остается. Не всегда почему то останавливается программа по бряку.
slabnoff
Имел подобный глюк на Филипсе:
гружу программу в ОЗУ, соотв. ремаплю вектора прерываний, ставлю брекпоинт на обработчик IRQ-прерывания прямо в стартапе запускаю - блин все виснет совершенно непредсказуемо. Начинаю разбираться - не ставлю брекпоинт - по нужному адресу вполне правильная инструкция, ставлю - какая-то фигня. На тот момент решил проблему просто - записал в программе до запуска прерываний правильный код в эту ячейку; с тех пор брекпоинты там не ставлю (сейчас в общем-то не страшно - отлаживаюсь во flash - внутреннего ОЗУ не хватает, а внешнее слишком медленное).

С уважением, Андрей Слабнов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.