|
Обработка математических ошибок в ARM |
|
|
|
Jan 14 2015, 14:36
|
Участник

Группа: Участник
Сообщений: 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) ни один из этих флагов не должен определять? Заранее спасибо.
|
|
|
|
|
 |
Ответов
|
Jan 15 2015, 12:28
|

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

|
Господа! Вы что, с ума сошли?  Переменную 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.
|
|
|
|
|
Jan 15 2015, 17:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Xenia @ Jan 15 2015, 18:28)  Господа! Вы что, с ума сошли?  Переменную errno в отдельную секцию выносить??? Все это можно сделать много проще, а не такими драконовскими мерами. Переменная errno в IAR уже практически в отдельной секции. Я же написал выше. И способ с MPU хорош тем, что не надо ничего перекомпилировать и вмешиваться в библиотеку. Цитата(cyrax0 @ Jan 15 2015, 19:46)  Попробовал так: define region MPU_region = mem:[from 0x20000000 to __ICFEDIT_region_RAM_start__ - 1]; place in MPU_region {section .bss object errno.o}; // Place in RAM_region .data, .bss, and .noinit place in RAM_region { readwrite }; Возможно place in RAM_region перекрывает директиву place in MPU_region - __iar_Errno у меня остался на прежнем месте в RAM. Так поменяйте их местами. Линкер считывает команды по порядку и последующая перекрывает действие предыдущих. Цитата(cyrax0 @ Jan 15 2015, 19:46)  А в ISR MPU можно получить, скажем, адрес функции, которая вызвала прерывание? Вы же уже открыли даташит на странице MPU? Так и прочитайте Я не использовал на практике MPU на Cortex, только на других CPU. Если адрес команды записи в errno нельзя получить из регистров MPU, то очевидно его можно получить из сохранённого контекста на входе в прерывание. Только не забудьте отключить write-back для защищаемого региона.
|
|
|
|
Сообщений в этой теме
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 Цитата(Xenia @ Jan 15 2015, 15:28) Одного... Jan 15 2015, 13:01  Xenia Цитата(scifi @ Jan 15 2015, 16:01) Конечн... Jan 15 2015, 13:29   scifi Цитата(Xenia @ Jan 15 2015, 16:29) Тогда ... Jan 15 2015, 13:47    cyrax0 Цитата(scifi @ Jan 15 2015, 17:47) Подозр... Jan 15 2015, 13:53     scifi Цитата(cyrax0 @ Jan 15 2015, 16:53) Делен... Jan 15 2015, 14:51 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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|