====== Подключение 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}}