реклама на сайте
подробности

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


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
amw
сообщение Jul 23 2007, 13:11
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



А стека хватает?


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
GenEv
сообщение Jul 24 2007, 05:30
Сообщение #3


Участник
*

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



Эээээ. Стек неконтролирую. А как узнать его размер? и как узнать что его не хватает?
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Jul 24 2007, 06:48
Сообщение #4


Частый гость
**

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Цитата(GenEv @ Jul 24 2007, 09:30) *
Эээээ. Стек неконтролирую. А как узнать его размер?

Обычно размер указывается в линкерном скрипте, формат зависит от компилятора

Цитата(GenEv @ Jul 24 2007, 09:30) *
и как узнать что его не хватает?

а)В самых вложенных функциях (в прерываниях) проверять текущее значение указателя стека
б)Заполнить какими-то "уникальными" значениями, например 0х12345678 и проверять что они не все затерлись
Go to the top of the page
 
+Quote Post
GenEv
сообщение Jul 24 2007, 07:44
Сообщение #5


Участник
*

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



Вот настройки стека:

Вот такую информацию дает Call Stack при брекпойнте в прерывание по UART0.

А вот это было при зависании:
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Jul 24 2007, 12:10
Сообщение #6


Частый гость
**

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Как я понял, это Keil, я с ним не знаком и оболочкой не пользуюсь. Могу только предложить:
1. Увеличить стеки IRQ и Supervisor в два раза. Посмотреть пройдут ли зависания.
2. Смотреть стек в прерывании через оболочку не совсем удобно, т.к. во первых надо бы смотреть на значение указателя стека и сравнивать его с отведенной под стек областью. А во вторых, при переходе в прерывание указатель стека меняет свое значение на "указатель стека в прерывании" и ни как не связан со стеком в обычном режиме.
Go to the top of the page
 
+Quote Post
amw
сообщение Jul 24 2007, 12:52
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Если действительно проблема со стеком - его размером - то вылетание программы раз в несколько минут (часов/дней) то тогда стека "в основном хватает", но при определенной комбинации вызовов его не хватает.
Я в таких случаях подставляю в ABT_handler вывод в RS232 всего содержимого стеков и регистров для каждого режима.
По полученному дампу стека и регистров можно вычислить, хватает ли его.

Вероятно тут может помочь JTAG отладка.

Еще DABT может происходить из попыток доступа к данным по невыровненным адресам, или по несуществующим.
У Вас нигде адреса не вычисляются?

А еще модификация глобальных переменных в функции, в то время как IRQ тоже ее модифицирует.


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
abcdefg
сообщение Jul 24 2007, 17:18
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 201
Регистрация: 23-01-06
Из: Msk
Пользователь №: 13 490



Цитата(amw @ Jul 24 2007, 16:52) *
Еще DABT может происходить из попыток доступа к данным по невыровненным адресам


Уверены? smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 24 2007, 21:36
Сообщение #9


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(GenEv @ Jul 24 2007, 10:44) *
А вот это было при зависании:

Abort LR (R14) смотрите. Он приведет вас ровно в ту точку где произошел DAbt.
Потом в дизассемблере смотрите место с адресом DAbt'a, а там уже и причину не трудно будет найти.
Go to the top of the page
 
+Quote Post
GenEv
сообщение Jul 25 2007, 06:42
Сообщение #10


Участник
*

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



Увеличил InterruptMode в 2 раза и все заработало!!!!
Спасибо всем!!!!
Go to the top of the page
 
+Quote Post
amw
сообщение Jul 25 2007, 14:53
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Цитата(abcdefg @ Jul 24 2007, 20:18) *
Уверены? smile.gif

Да.
Если камень соответствует спецификации.
А то были какие-то непонятки с LPC. Тут на форуме обсуждалось.


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 25 2007, 16:07
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th August 2025 - 00:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.0146 секунд с 7
ELECTRONIX ©2004-2016