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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Не могу понять природу исключения
Jenya7
сообщение Jun 5 2018, 13:39
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Есть функция в которой вызывается другая функция
Код
d_RangeToTarget = round_int16(s1553_AH64A_Conv.Range_AID, 1.0);
при попадании на эту строчку контролер уходит в исключение и я не могу отследить причину так как я не могу даже сделать Step Into.сама функция ничего особобенного не представляет
Код
double round_int16(double num2rnd, double scale)
{
    double l_temp_mod = 0, l_num_after_rnd = 0, l_temp_mod2 = 0, temp_scale =0;
    
    //int32_t num_int =0;
    //num_int = (uint32_t)num2rnd;

    //l_temp_mod = fmod(num2rnd, scale);

    if(l_temp_mod < 0.0)
    {
        l_temp_mod2 = l_temp_mod * (-1.0);
        temp_scale  = scale * (-1.0);
    }
    else
    {
        l_temp_mod2 = l_temp_mod;
        temp_scale = scale;
    }

    if ((l_temp_mod2)>= (scale/2))
        l_num_after_rnd = num2rnd- (l_temp_mod) + temp_scale;
    else
        l_num_after_rnd = num2rnd- l_temp_mod;

    return l_num_after_rnd;
}
как можно отследить проблему?

Сообщение отредактировал Jenya7 - Jun 5 2018, 13:40
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 5 2018, 13:49
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Jun 5 2018, 16:39) *
как можно отследить проблему?

После попадания в исключение можно узнать адрес из стекфрейма (контроллер по умолчанию - Cortex-M, ага).
Но я бы прежде всего посмотрел определение s1553_AH64A_Conv.Range_AID, очень вероятно, что выполняется
чтение двойного слова с недопустимым выравниванием.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 5 2018, 14:34
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(aaarrr @ Jun 5 2018, 19:49) *
После попадания в исключение можно узнать адрес из стекфрейма (контроллер по умолчанию - Cortex-M, ага).
Но я бы прежде всего посмотрел определение s1553_AH64A_Conv.Range_AID, очень вероятно, что выполняется
чтение двойного слова с недопустимым выравниванием.
да. Cortex-М4ю
вроде все нормально
Код
typedef struct
{
     double Range_AID;
      ...........................    
      ..........................
}
muxbus_sDataAfterConvert_AH64A_messages;

muxbus_sDataAfterConvert_AH64A_messages s1553_AH64A_Conv;

View -> Call Stack показывает вхождение в эту функцию и все - никакой индикации.

Сообщение отредактировал Jenya7 - Jun 5 2018, 14:35
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 5 2018, 15:02
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Jun 5 2018, 17:34) *
View -> Call Stack

Не то, нужен Stack Frame. Можно просто посмотреть содержимое памяти по указателю SP - по смещению 0x14 будет адрес инструкции, вызвавшей исключение.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 5 2018, 15:16
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(aaarrr @ Jun 5 2018, 21:02) *
Не то, нужен Stack Frame. Можно просто посмотреть содержимое памяти по указателю SP - по смещению 0x14 будет адрес инструкции, вызвавшей исключение.

SP = 0x2000FF68 - он не изменился после Step Into.

я не понимаю чем эта функция не понравилась контролеру и до нее и после нее есть куча других функций и все работают.

Сообщение отредактировал Jenya7 - Jun 5 2018, 15:19
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 5 2018, 15:26
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Jun 5 2018, 18:16) *
SP = 0x2000FF68 - он не изменился после Step Into.

А если бы он был равен 0x12345678 - это что нибудь прояснило, как думаете?
Содержимое стек-фрейма. Из него адрес. По адресу в дизассемблере инструкцию. По инструкции и содержимому регистров делаем выводы.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 5 2018, 15:41
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(aaarrr @ Jun 5 2018, 21:26) *
А если бы он был равен 0x12345678 - это что нибудь прояснило, как думаете?
Содержимое стек-фрейма. Из него адрес. По адресу в дизассемблере инструкцию. По инструкции и содержимому регистров делаем выводы.

извиняюсь за тупость - а где есть содержимое стек-фрейма?

по дизасембли - прыгает в default_isr - почему непонятно

Сообщение отредактировал Jenya7 - Jun 5 2018, 15:45
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 5 2018, 16:05
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Jun 5 2018, 18:41) *
извиняюсь за тупость - а где есть содержимое стек-фрейма?

В памяти, по адресу, на который указывает SP.

Цитата(Jenya7 @ Jun 5 2018, 18:41) *
по дизасембли - прыгает в default_isr - почему непонятно

Наверное, обработчика для fault'а нет.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 6 2018, 08:09
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Вынесите функцию из параметра.
Вместо функции "разверните" ее код в Inline.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 6 2018, 08:41
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(k155la3 @ Jun 6 2018, 14:09) *
Вынесите функцию из параметра.
Вместо функции "разверните" ее код в Inline.
функция имела следующий вид
Код
void data_calculation_AH64A(uint8_t flag)
{
    switch (flag)
    {
        case MSG_04R04:
        if(s1553_AH64A_Conv.TADS_Operate_CMD == 1)
            {
                d_RangeToTarget = round_int16(s1553_AH64A_Conv.Range_AID, 1.0);
            }
        else
            {
                d_RangeToTarget = 0;
            }

        d_PitchAngle = round_int16(s1553_AH64A_Conv.Pitch_AID, 0.1);
        d_RollAngle = round_int16(s1553_AH64A_Conv.Roll_AID, 0.1);
        b_RangeValidy = s1553_AH64A_Conv.TADS_Operate_CMD;
        b_PitchAngleValidy = s1553_AH64A_Conv.Pitch_AID_Valid;
        b_RollAngleValidy = s1553_AH64A_Conv.Roll_AID_Valid;
    break;    
   //и так далее
}

для проверки изменил
Код
void data_calculation_AH64A(uint8_t flag)
{
    double dval=0;
    
    switch (flag)
    {
        case MSG_04R04:
        if(s1553_AH64A_Conv.TADS_Operate_CMD == 1)
            {
                d_RangeToTarget = round_int16(dval, 1.0);
                s1553_AH64A_Conv.Range_AID = dval;
            }
        else
            {
        d_RangeToTarget = 0;
            }

        d_PitchAngle = round_int16(s1553_AH64A_Conv.Pitch_AID, 0.1);
        d_RollAngle = round_int16(s1553_AH64A_Conv.Roll_AID, 0.1);
        b_RangeValidy = s1553_AH64A_Conv.TADS_Operate_CMD;
        b_PitchAngleValidy = s1553_AH64A_Conv.Pitch_AID_Valid;
        b_RollAngleValidy = s1553_AH64A_Conv.Roll_AID_Valid;
    break;

на строчке double dval=0; вываливается в исключение.
Такое может быть из за неправильного линкер файла?
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 6 2018, 10:17
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Если обычный стек - может "зашкал" ? Или в линк-файле недостаточно или неправильно указан сегмент стека. (или в опциях проекта)
Попробуйте
double dval=0.; (хотя и неявно должно приводить)
double dval=0.f;
static double dval=0.;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 6 2018, 11:08
Сообщение #12


Гуру
******

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



QUOTE (Jenya7 @ Jun 6 2018, 11:41) *
на строчке double dval=0; вываливается в исключение.
Очередной конкурс на телепатию? Какая ассемблерная команда выполняется, каково содержимое регистров, занятых в команде, какой в конце-концов процессор? Вы боитесь при приблежении к проблеменому участку открывать окно дизассемблера и ходить в нем по ассемблерным командам?

Я не помню зачем, но ABI требует выравнивание стека на 8 байт. Вроде аргументировали работой с плавающей точкой. Не оно? Процессор какой? Работа с плавающей точкой аппаратная или программная?


--------------------
На любой вопрос даю любой ответ
"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
Jenya7
сообщение Jun 6 2018, 11:33
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Jun 6 2018, 16:08) *
Очередной конкурс на телепатию? Какая ассемблерная команда выполняется, каково содержимое регистров, занятых в команде, какой в конце-концов процессор? Вы боитесь при приблежении к проблеменому участку открывать окно дизассемблера и ходить в нем по ассемблерным командам?

Я не помню зачем, но ABI требует выравнивание стека на 8 байт. Вроде аргументировали работой с плавающей точкой. Не оно? Процессор какой? Работа с плавающей точкой аппаратная или программная?
Это Kinretis MK10. debug1 - это я остановился на строчке где вылетает. debug2 - следующий шаг - вылет в исключение.

между двумя этими событиями нет ничего что бы объяснило что вызвало default_isr.

Сообщение отредактировал Jenya7 - Jun 6 2018, 11:38
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 6 2018, 12:10
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



По map-файлу проверьте еще где (адреса) размещена s1553_AH64A_Conv.
Для поиска вылета попробуйте изменить для нее класс памяти (например, вынести в глобальные под __root).

Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 6 2018, 13:18
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Jun 6 2018, 14:33) *
debug2 - следующий шаг - вылет в исключение.

Вот тут откройте окошко с памятью и посмотрите содержимое с адреса 0x2000ff68.

Или в окошке дизассемблера по шагам до исключения пройдите из состояния debug1.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th April 2024 - 05:16
Рейтинг@Mail.ru


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