Я пишу код для платы запуска Texas Instruments Stellaris Launchpad (Cortex-M4F, чип LM4F120H5QR ). Я использую библиотеку IRMP для инфракрасного декодирования, которая отлично работает, если я не использую математику с плавающей запятой за пределами ISR. Всего одна операция, такая как в
MAP_SysCtlDelay((MAP_SysCtlClockGet())/ 30.0);
ломает библиотеку IRMP. Чип все еще работает, IRMP вызывает все необходимые функции, передачи UART работают, но IRMP больше не может декодировать инфракрасный прием.
В самом верху моей main
функции у меня есть:
// Enable FPU
MAP_FPULazyStackingEnable();
MAP_FPUEnable ();
На самом деле, если я закомментирую эти строки, программа просто зависнет во время инициализации.
Я пробовал несколько разновидностей этих функций включения FPU (ROM_, MAP_, FPUStackingEnable, FPULazyEnable), но, похоже, ничто не решает проблему.
Последние 4 часа гугления оказались бесполезными, поэтому я надеялся найти ответ здесь.
Редактировать: еще одна странность: если я компилирую с -O0, IRMP также ничего не декодирует. Как только я устанавливаю оптимизацию на O1 или выше, она снова начинает работать (при условии, что арифметика с плавающей запятой не выполняется вне процедуры ISR таймера и функций, которые она вызывает).
О, и в случае, если это поможет, arm-none-eabi-gcc --version
дает:
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305]
Я компилирую со следующими параметрами:
-DPART_LM4F120H5QR -DARM_MATH_CM4 -DTARGET_IS_BLIZZARD_RA1 -I$SOMEDIR/stellarisware
-Os -Wall -std=gnu99 -c -fmessage-length=0 -fsingle-precision-constant -mcpu=cortex-m4
-mfpu=fpv4-sp-d16 -mthumb -mfloat-abi=softfp -ffunction-sections -fdata-sections
Редактировать 2: я должен добавить, что в коде IRMP не происходит реальных вычислений с плавающей запятой. То есть: все переменные являются целыми числами. Однако существует множество определений, которые являются промежуточными поплавками, например:
#define IRMP_KEY_REPETITION_LEN (uint16_t)(F_INTERRUPTS * 150.0e-3 + 0.5)
Эти константы сравниваются с другими uint16_t
типами в реальном коде. Я не совсем уверен, почему для этого требуется арифметика FP в коде времени выполнения, это все фиксированные значения, которые можно сложить в целые числа.
Почему бы вам не попытаться удалить все вычисления с плавающей запятой из подпрограмм обслуживания прерываний. Многие люди сказали бы, что это не должно быть там в первую очередь.
Предварительно вычисляйте значения с плавающей запятой в основном потоке кода, чтобы их не нужно было использовать в ISR. Это может потребовать некоторого переосмысления используемых алгоритмов, но часто приводит к более надежному и компактному коду.
Питер Джей
АВХ
АВХ
АВХ
Майкл Карас
Майкл Карас
АВХ
АВХ
АВХ