GenEv 0 23 июля, 2007 Опубликовано 23 июля, 2007 (изменено) · Жалоба Проект для 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; } Вообщем что делать ума не приложу. Что то в уме смутно бродит про защиту выполнения кода от прерывания. Есть ли такое? и поможет ли? Изменено 23 июля, 2007 пользователем GenEv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amw 0 23 июля, 2007 Опубликовано 23 июля, 2007 · Жалоба А стека хватает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenEv 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба Эээээ. Стек неконтролирую. А как узнать его размер? и как узнать что его не хватает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey Bishletov 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба Эээээ. Стек неконтролирую. А как узнать его размер? Обычно размер указывается в линкерном скрипте, формат зависит от компилятора и как узнать что его не хватает? а)В самых вложенных функциях (в прерываниях) проверять текущее значение указателя стека б)Заполнить какими-то "уникальными" значениями, например 0х12345678 и проверять что они не все затерлись Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenEv 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба Вот настройки стека: Вот такую информацию дает Call Stack при брекпойнте в прерывание по UART0. А вот это было при зависании: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey Bishletov 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба Как я понял, это Keil, я с ним не знаком и оболочкой не пользуюсь. Могу только предложить: 1. Увеличить стеки IRQ и Supervisor в два раза. Посмотреть пройдут ли зависания. 2. Смотреть стек в прерывании через оболочку не совсем удобно, т.к. во первых надо бы смотреть на значение указателя стека и сравнивать его с отведенной под стек областью. А во вторых, при переходе в прерывание указатель стека меняет свое значение на "указатель стека в прерывании" и ни как не связан со стеком в обычном режиме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amw 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба Если действительно проблема со стеком - его размером - то вылетание программы раз в несколько минут (часов/дней) то тогда стека "в основном хватает", но при определенной комбинации вызовов его не хватает. Я в таких случаях подставляю в ABT_handler вывод в RS232 всего содержимого стеков и регистров для каждого режима. По полученному дампу стека и регистров можно вычислить, хватает ли его. Вероятно тут может помочь JTAG отладка. Еще DABT может происходить из попыток доступа к данным по невыровненным адресам, или по несуществующим. У Вас нигде адреса не вычисляются? А еще модификация глобальных переменных в функции, в то время как IRQ тоже ее модифицирует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iShustov 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба Еще DABT может происходить из попыток доступа к данным по невыровненным адресам Уверены? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 24 июля, 2007 Опубликовано 24 июля, 2007 · Жалоба А вот это было при зависании: Abort LR (R14) смотрите. Он приведет вас ровно в ту точку где произошел DAbt. Потом в дизассемблере смотрите место с адресом DAbt'a, а там уже и причину не трудно будет найти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenEv 0 25 июля, 2007 Опубликовано 25 июля, 2007 · Жалоба Увеличил InterruptMode в 2 раза и все заработало!!!! Спасибо всем!!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amw 0 25 июля, 2007 Опубликовано 25 июля, 2007 · Жалоба Уверены? :) Да. Если камень соответствует спецификации. А то были какие-то непонятки с LPC. Тут на форуме обсуждалось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 25 июля, 2007 Опубликовано 25 июля, 2007 · Жалоба Да. Если камень соответствует спецификации. Берем спецификацию, т.е. документ имени 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.И никаких абортов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться