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

 
 
> Обработка математических ошибок в ARM
cyrax0
сообщение Jan 14 2015, 14:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 9-12-14
Пользователь №: 84 046



Здравствуйте!
Я использую IAR EWARM 6.40 и STM32F407 (с FPU). Нужно останавливать контроллер при возникновении математических ошибок, например, при log(-1). В этом случае я получаю NaN в качестве результата, но по умолчанию никакого вызова функции или exception не происходит. Нету ли для ARM функции, аналогичной стандартной _matherr (math.h)? На других архитектурах она вызывается при следующих ошибках:

Код
    DOMAIN = 1,    /* argument domain error -- log (-1)        */
    SING,          /* argument singularity  -- pow (0,-2))     */
    OVERFLOW,      /* overflow range error  -- exp (1000)      */
    UNDERFLOW,     /* underflow range error -- exp (-1000)     */
    TLOSS,         /* total loss of significance -- sin(10e70) */
    PLOSS,         /* partial loss of signif. -- not used      */
    STACKFAULT     /* floating point unit stack overflow       */

Через FPU все эти ошибки, как я понял, тоже нельзя определить, например, регистр FPSCR Cortex-M4 среди битов исключений domain error не имеет:

Bit 7 IDC: Input denormal cumulative exception bit. Cumulative exception bit for floating-point
exception.
1: Indicates that the corresponding exception occurred since 0 was last written to it.
Bit 6:5 Reserved
Bit 4 IXC: Inexact cumulative exception bit. Cumulative exception bit for floating-point exception.
1: Indicates that the corresponding exception occurred since 0 was last written to it.
Bit 3 UFC: Underflow cumulative exception bit. Cumulative exception bit for floating-point exception.
1: Indicates that the corresponding exception occurred since 0 was last written to it.
Bit 2 OFC: Overflow cumulative exception bit. Cumulative exception bit for floating-point exception.
1: Indicates that the corresponding exception occurred since 0 was last written to it.
Bit 1 DZC: Division by zero cumulative exception bit. Cumulative exception bit for floating-point
exception. 1: Indicates that the corresponding exception occurred since 0 was last written to it.
Bit 0 IOC: Invalid operation cumulative exception bit. Cumulative exception bit for floating-point
exception. 1: Indicates that the corresponding exception occurred since 0 was last written to it.


Мне даже переполнение при результате операции 0.Infinite не удалось зафиксировать в этих флагах. Может, что-то не так сделал, но вроде бы в любом случае ситуацию log(-1) ни один из этих флагов не должен определять?
Заранее спасибо.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Xenia
сообщение Jan 15 2015, 12:28
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Господа! Вы что, с ума сошли? sm.gif Переменную errno в отдельную секцию выносить??? Все это можно сделать много проще, а не такими драконовскими мерами.

Заметим, что ни в одной функции, и log() в том числе, значение errno не присваивается явно, а только через вызов дефайнов:
Код
#define _FERAISE_INVALID()    { errno = EDOM;   }
#define _FERAISE_DIVBYZERO()  { errno = ERANGE; }
#define _FERAISE_OVERFLOW()   { errno = ERANGE; }
#define _FERAISE_UNDERFLOW()  { errno = ERANGE; }
#define _FERAISE_INEXACT()

Так что, если вы взялись за дело настолько серьезно, что решили перекомпилировать библиотеку, то было бы куда проще переопределить эти 5 дефиниций на свои функции.

Однако я полагаю, что и в этом нет большой нужды, т.к. эти дефиниции определены в хидере xmath.h не жестко, а условно:
Код
#if defined(math_errhandling) && math_errhandling == MATH_ERRNO

  /* Optimization of the _Feraise function when the IAR default is used. */
  #define _FERAISE_INVALID()    { errno = EDOM;   }
  #define _FERAISE_DIVBYZERO()  { errno = ERANGE; }
  #define _FERAISE_OVERFLOW()   { errno = ERANGE; }
  #define _FERAISE_UNDERFLOW()  { errno = ERANGE; }
  #define _FERAISE_INEXACT()

#else
... // здесь определена функция _Feraise()

#define _FERAISE_INVALID()    _Feraise(FE_INVALID)
#define _FERAISE_DIVBYZERO()  _Feraise(FE_DIVBYZERO)
#define _FERAISE_OVERFLOW()   _Feraise(FE_OVERFLOW)
#define _FERAISE_UNDERFLOW()  _Feraise(FE_UNDERFLOW)
#define _FERAISE_INEXACT()    _Feraise(FE_INEXACT)

#endif

Т.е. достаточно определить "math_errhandling" иначе, чем MATH_ERRNO, чтобы определение этих дефиниций изменилось на альтернативное, с явным вызовом функции _Feraise(), получающей код ошибки в качестве параметра.

Саму функцию _Feraise() при желании можно легко заменить на свою (т.к. самодельный вариант линкуется раньше библиотечного), а можно оставить той, что написана авторами компилятора - она там errno присваивает, а потом исключение вызывает.

Одного только я уверенно сказать не могу, нужно ли для этого перекомпилировать библиотеку или достататочно будет определить math_errhandling перед включением хидера xmath.h.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 15 2015, 13:01
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Xenia @ Jan 15 2015, 15:28) *
Одного только я уверенно сказать не могу, нужно ли для этого перекомпилировать библиотеку или достататочно будет определить math_errhandling перед включением хидера xmath.h.

Конечно перекомпилировать.
Но перекомпиляция библиотеки сопряжена с неудобствами. К примеру, чтобы подготовить новый компьютер к сборке программ, нужно помимо установки яра колдовать с библиотекой. В общем, надо взвешивать плюсы и минусы.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jan 15 2015, 13:29
Сообщение #4


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(scifi @ Jan 15 2015, 16:01) *
Конечно перекомпилировать.
Но перекомпиляция библиотеки сопряжена с неудобствами. К примеру, чтобы подготовить новый компьютер к сборке программ, нужно помимо установки яра колдовать с библиотекой. В общем, надо взвешивать плюсы и минусы.


Тогда уж гораздо проще перекомпилировать один единственный модуль, в котором функция log() находится sm.gif, а потом добавить этот объектник в проект. Жалко библиотеку курочить.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 15 2015, 13:47
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Xenia @ Jan 15 2015, 16:29) *
Тогда уж гораздо проще перекомпилировать один единственный модуль, в котором функция log() находится sm.gif, а потом добавить этот объектник в проект. Жалко библиотеку курочить.

Подозреваю, что топикстартера не только логарифм интересует. А если он ещё захочет ловить деление на ноль, то ему точно от Си++ и перегрузки операторов не отвертеться.
Go to the top of the page
 
+Quote Post
cyrax0
сообщение Jan 15 2015, 13:53
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 9-12-14
Пользователь №: 84 046



Цитата(scifi @ Jan 15 2015, 17:47) *
Подозреваю, что топикстартера не только логарифм интересует. А если он ещё захочет ловить деление на ноль, то ему точно от Си++ и перегрузки операторов не отвертеться.

Деление на ноль как раз ловится элементарно:
SCB->CCR |= 0x10;
Без этого (по умолчанию) деление на ноль дает ноль.
С этим - HardFault.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- cyrax0   Обработка математических ошибок в ARM   Jan 14 2015, 14:36
- - scifi   Цитата(cyrax0 @ Jan 14 2015, 17:36) Я исп...   Jan 14 2015, 14:55
- - cyrax0   А можно поподробнее, что за errno? Отмечу еще раз,...   Jan 14 2015, 17:02
|- - scifi   Цитата(cyrax0 @ Jan 14 2015, 20:02) А мож...   Jan 14 2015, 19:17
- - _Pasha   Насколько я помню, Вам нужно переопределить хандле...   Jan 14 2015, 19:15
|- - cyrax0   ЦитатаНасколько я помню, Вам нужно переопределить ...   Jan 14 2015, 19:43
|- - jcxz   Цитата(cyrax0 @ Jan 15 2015, 01:43) Если ...   Jan 15 2015, 05:26
|- - scifi   Цитата(jcxz @ Jan 15 2015, 08:26) Через M...   Jan 15 2015, 06:57
- - Xenia   Цитата(cyrax0 @ Jan 14 2015, 20:02) А мож...   Jan 14 2015, 22:42
|- - cyrax0   Цитата(Xenia @ Jan 15 2015, 02:42) А чем ...   Jan 15 2015, 07:59
|- - jcxz   Цитата(cyrax0 @ Jan 15 2015, 13:59) Прико...   Jan 15 2015, 08:20
- - _Pasha   Собственно можно пойти далеко в обход: написать ну...   Jan 15 2015, 04:32
- - cyrax0   Не очень понимаю, с какой стати errno может быть в...   Jan 15 2015, 08:35
|- - jcxz   Цитата(cyrax0 @ Jan 15 2015, 14:35) Не оч...   Jan 15 2015, 10:14
- - scifi   Цитата(cyrax0 @ Jan 15 2015, 10:59) У нас...   Jan 15 2015, 09:08
|- - jcxz   Цитата(scifi @ Jan 15 2015, 15:08) Не фак...   Jan 15 2015, 10:27
- - cyrax0   ЦитатаА если привлечь Си++, то можно и операторы п...   Jan 15 2015, 09:25
|- - scifi   Цитата(cyrax0 @ Jan 15 2015, 12:25) В ито...   Jan 15 2015, 10:22
|- - klen   здравствуйте. вставлю свои 5 копеек. 1. FPU вычисл...   Jan 16 2015, 07:25
||- - scifi   Цитата(cyrax0 @ Jan 15 2015, 16:53) Делен...   Jan 15 2015, 14:51
|- - jcxz   Цитата(Xenia @ Jan 15 2015, 18:28) Господ...   Jan 15 2015, 17:08
- - cyrax0   Цитата(scifi @ Jan 15 2015, 14:22) Там ес...   Jan 15 2015, 13:46
- - cyrax0   Цитата(jcxz @ Jan 15 2015, 21:08) Так пом...   Jan 16 2015, 06:09
|- - jcxz   Цитата(cyrax0 @ Jan 16 2015, 12:09) Я поп...   Jan 16 2015, 17:55
- - WitFed   Ещё 1 коп: обычно можно переопределить "систе...   Jan 16 2015, 09:19


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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:57
Рейтинг@Mail.ru


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