|
DAbt_Handler?A или проблема с прерыванием?, Можно ли как то отложить прерывания? |
|
|
|
Jul 23 2007, 12:42
|

Участник

Группа: Участник
Сообщений: 16
Регистрация: 29-11-06
Пользователь №: 22 884

|
Проект для LPC2294.Вообщем проблема не понятная. Смысл такой. Есть основной цикл. по прерыванию набирается пакет байтов. Так вот если убрать AppBrake = GetAppBrake(); //____________________________________________ Опрос углов _____________________________ Azimut.Angle = GetAngle() + Azimut.Corr; Elev.Angle = 14.5 + Elev.Corr;
... // Рсчеты, расчетыт.е. различные расчеты, то все работает отлично, стоит только добавить фунцию GetAngle(); так возникает проблема DAbt_Handler?A, причем все время по разному. Обмен может происходить 30 секунд, минуту, но все равно срабатывает прерывание по DAbt_Handler?A. Код while(1) { AppBrake = GetAppBrake(); //____________________________________________ Опрос углов _____________________________ Azimut.Angle = GetAngle() + Azimut.Corr; Elev.Angle = 14.5 + Elev.Corr;
... // Рсчеты, расчеты //___________________________________________ Обработка команд по RS _________________ switch (Action) // !!!!!! { case PACK: IDCommand(PackNumber); Action = FALSE; for (cl = 0; cl < 20; cl ++) PackRead[cl] = 0; break; case ERR_CHECK: WriteData(PackRead[1], "d", 1); Action = FALSE; for (cl = 0; cl < 20; cl ++) PackRead[cl] = 0; break; case ERR_PACK: WriteData(PackRead[1], "e", 1); Action = FALSE; for (cl = 0; cl < 20; cl ++) PackRead[cl] = 0; break; } } Функция GetAngle() Код float GetAngle() { USHORT *Adress; USHORT go, to; int s, c, turn; float res; c = 0; go = 0; to = 0; //====================== Азимут ===================================================== Adress = 0x82020000; //грубый отсчет IOCLR1 = SP(21); go = *Adress; IOSET1 = SP(21);
Adress = 0x82040000; //точный отсчет IOCLR1 = 0x200000; to = *Adress; IOSET1 = 0x200000; s = (go & 0x7FF) - (to >> 5); if (s > 1500) c = 2047; if (s < -1500) c = - 2047; go = go & 0xF800; res = go + (to >> 5) + c; turn = IOPIN0; turn = (turn >> 19) & 1; if ( (turn == 1) && (res < 50000) ) res += 65536; res = res * 360 / 65536; return res - 5; } Вообщем что делать ума не приложу. Что то в уме смутно бродит про защиту выполнения кода от прерывания. Есть ли такое? и поможет ли?
Сообщение отредактировал GenEv - Jul 23 2007, 12:43
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Jul 24 2007, 06:48
|
Частый гость
 
Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557

|
Цитата(GenEv @ Jul 24 2007, 09:30)  Эээээ. Стек неконтролирую. А как узнать его размер? Обычно размер указывается в линкерном скрипте, формат зависит от компилятора Цитата(GenEv @ Jul 24 2007, 09:30)  и как узнать что его не хватает? а)В самых вложенных функциях (в прерываниях) проверять текущее значение указателя стека б)Заполнить какими-то "уникальными" значениями, например 0х12345678 и проверять что они не все затерлись
|
|
|
|
|
Jul 24 2007, 07:44
|

Участник

Группа: Участник
Сообщений: 16
Регистрация: 29-11-06
Пользователь №: 22 884

|
Вот настройки стека:  Вот такую информацию дает Call Stack при брекпойнте в прерывание по UART0.  А вот это было при зависании:
|
|
|
|
|
Jul 24 2007, 12:52
|
Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847

|
Если действительно проблема со стеком - его размером - то вылетание программы раз в несколько минут (часов/дней) то тогда стека "в основном хватает", но при определенной комбинации вызовов его не хватает. Я в таких случаях подставляю в ABT_handler вывод в RS232 всего содержимого стеков и регистров для каждого режима. По полученному дампу стека и регистров можно вычислить, хватает ли его.
Вероятно тут может помочь JTAG отладка.
Еще DABT может происходить из попыток доступа к данным по невыровненным адресам, или по несуществующим. У Вас нигде адреса не вычисляются?
А еще модификация глобальных переменных в функции, в то время как IRQ тоже ее модифицирует.
--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть. © Lewis Carroll. Alice's adventures in wonderland.
|
|
|
|
|
Jul 25 2007, 14:53
|
Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847

|
Цитата(abcdefg @ Jul 24 2007, 20:18)  Уверены?  Да. Если камень соответствует спецификации. А то были какие-то непонятки с LPC. Тут на форуме обсуждалось.
--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть. © Lewis Carroll. Alice's adventures in wonderland.
|
|
|
|
|
Jul 25 2007, 16:07
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(amw @ Jul 25 2007, 17:53)  Да. Если камень соответствует спецификации. Берем спецификацию, т.е. документ имени ARM под номером ARM DDI0029E, ARM7TDMI Data Sheet. Стр. 4-29, инструкции LDR, STR: Цитата A word load (LDR) will normally use a word aligned address. However, an address offset from a word boundary will cause the data to be rotated into the register so that the addressed byte occupies bits 0 to 7. This means that half-words accessed at offsets 0 and 2 from the word boundary will be correctly loaded into bits 0 through 15 of the register. Стр. 4-41, инструкции LDM, STM: Цитата The address should normally be a word aligned quantity and non-word aligned addresses do not affect the instruction. However, the bottom 2 bits of the address will appear on A[1:0] and might be interpreted by the memory system. И никаких абортов.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|