====== Подключение FPU для 1986ВЕ8Т в Keil ====== Для начала работы с микроконтроллером 1986ВЕ8Т необходимо установить отдельный Pack. Этот Pack можно скачать с [[https://ic.milandr.ru/upload/iblock/239/2396943aadd08e7a592e6af1d320461b.zip|сайта]] или запросить в [[http://ic.milandr.ru/contacts/|техподдержке]]. Ставится он так-же, как и основной Pack для остальных микроконтроллеров, что было описано [[PROG:Start:SetupKeil|здесь]]. Помимо этого, для Keil должен быть уставлен [[http://www2.keil.com/mdk5/legacy|Legacy support for ARM Cortex-M devices]]. Без установки этой поддержки, проект будет выдавать ошибки о том, что файл //core_cm4.h// не найден. Ведь его действительно почему-то нет в Pack от Миландр. //(Целиком проект по статье доступен на [[https://github.com/StartMilandr/1.4-FPU_VE8|GitHub]].)// При создании нового проекта необходимо выбрать микроконтроллер в секции Cortex-M4F. {{prog:fpu:fpu_device.png}} В данном примере нам не потребуются блоки периферии, поэтому выбираем только пункты, необходимые для запуска. {{prog:fpu:fpu_pack.png}} Теперь в проекте создадим файл //main.c// и напишем в нем небольшой тест. int main(void) { static float a = 1.2; static float b = 1.2; volatile float rMul, rAdd, rSub, rDiv; while (1) { // Clear rMul = rAdd = rSub = rDiv = 0; // Calc Result rMul = a * b; rAdd = a + b; rSub = a - b; rDiv = a / b; } } Если на данном этапе собрать проект и запустить, то можно увидеть в окне дизассемблера, что вся работа с переменными типа //float// реализована программно в целочисленном режиме. Такая реализация занимает большое количество команд и тактов. Но в ядре Cortex_M4F есть встроенный блок (FPU) для работы с переменными типа **float**. Работа с переменными типа **double** в данном ядре аппаратно не поддерживается и реализуется компилятором программно. Обычно, если в //Pack// от производителя указано, что //Target// содержит //FPU//, то на закладке //Target// опций проекта появляется выбор необходимого режима, как это представлено [[http://www.keil.com/support/docs/3716.htm|здесь]]. Но для МК 1986ВЕ8Т такого выбора не появляется, поэтому необходимо организовать это в ручном режиме. {{prog:fpu:fpu_target.png}} ==== 1 - Опции компилятору и линкеру ==== Для того, чтобы компилятор генерил инструкции аппаратной работы с //float// необходимо выставить ему соответствующие опции. Полный перечень опций доступен [[http://www.keil.com/support/man/docs/armcc/armcc_chr1359124920656.htm|здесь]]. {{prog:fpu:fpu_cpp.png}} Такие же опции необходимо задать и линкеру {{prog:fpu:fpu_linker.png}} ==== 2 - Активация FPU в ядре ==== По умолчанию блок FPU выключен, для его активации необходимо в микроконтроллере выставить необходимые биты //CP10// и //CP10// в регистре //SCB->CPACR//. Обычно это реализовано в функции //SystemInit()// библиотеки CMSIS, но если открыть файл //startup_1986ve8t.s// то видно, что вызова //SystemInit()// при старте нет. Поэтому добавим выставление этих бит в реализацию Reset_Handler. Такую же реализацию можно найти в документации - [[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/Chdbebfc.html|здесь]]. Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main ; --- FPU Enable --- ; CPACR is located at address 0xE000ED88 LDR.W R0, =0xE000ED88 ; Read CPACR LDR R1, [R0] ; Set bits 20-23 to enable CP10 and CP11 coprocessors ORR R1, R1, #(0xF << 20) ; Write back the modified value to the CPACR STR R1, [R0]; wait for store to complete DSB ;reset pipeline now the FPU is enabled ISB LDR R0,=__main BX R0 ENDP =====Сборка проекта===== Теперь проект можно собрать и запустить. Но МК 1986ВЕ8Т содержит вместо Flash памяти, однократно программируемую память (OTP), поэтому вся обкатка программ происходит из ОЗУ в режиме отладчика. Ниже приведены скриншоты остальных настроек проекта, необходимых для такого запуска. Для запуска из ОЗУ необходимо подключить //Start.ini// файл: {{prog:fpu:fpu_debug.png}} Вот его содержимое: FUNC void Setup (unsigned int region) { region &= 0xFFFFF000; SP = _RDWORD(region); // Setup Stack Pointer PC = _RDWORD(region + 4); // Setup Program Counter _WDWORD(0xE000ED08, region); // Setup Vector Table Offset Register } Setup(0x20006000); // Get ready to execute image in SRAM or whatever region it is in g,main Закладка //Debug - Settings - Debug// настроена стандартно: {{prog:fpu:fpu_dbg_jtag.png}} В закладке //Debug - Settings - Flash Download// необходимо выключить любую работу с Flash памятью: {{prog:fpu:fpu_dbg_download.png}} Выключена загрузка Flash и в закладке Utilites: {{prog:fpu:fpu_utils.png}} =====Проверка примера===== Результат работы примера представлен на картинке ниже. В окне //Call Stack// видны значения переменных и результаты математических операций. В окне дизассемблера виден получившийся код. Он значительно отличается от кода без использования FPU. {{prog:fpu:fpu_calc.png}}