Инструменты пользователя

Инструменты сайта


prog:spec:fpu_ve8

Подключение FPU для 1986ВЕ8Т в Keil

Для начала работы с микроконтроллером 1986ВЕ8Т необходимо установить отдельный Pack. Этот Pack можно скачать с сайта или запросить в техподдержке. Ставится он так-же, как и основной Pack для остальных микроконтроллеров, что было описано здесь.

Помимо этого, для Keil должен быть уставлен Legacy support for ARM Cortex-M devices. Без установки этой поддержки, проект будет выдавать ошибки о том, что файл core_cm4.h не найден. Ведь его действительно почему-то нет в Pack от Миландр.

(Целиком проект по статье доступен на GitHub.)

При создании нового проекта необходимо выбрать микроконтроллер в секции Cortex-M4F.

В данном примере нам не потребуются блоки периферии, поэтому выбираем только пункты, необходимые для запуска.

Теперь в проекте создадим файл 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 опций проекта появляется выбор необходимого режима, как это представлено здесь. Но для МК 1986ВЕ8Т такого выбора не появляется, поэтому необходимо организовать это в ручном режиме.

1 - Опции компилятору и линкеру

Для того, чтобы компилятор генерил инструкции аппаратной работы с float необходимо выставить ему соответствующие опции. Полный перечень опций доступен здесь.

Такие же опции необходимо задать и линкеру

2 - Активация FPU в ядре

По умолчанию блок FPU выключен, для его активации необходимо в микроконтроллере выставить необходимые биты CP10 и CP10 в регистре SCB→CPACR.

Обычно это реализовано в функции SystemInit() библиотеки CMSIS, но если открыть файл startup_1986ve8t.s то видно, что вызова SystemInit() при старте нет. Поэтому добавим выставление этих бит в реализацию Reset_Handler. Такую же реализацию можно найти в документации - здесь.

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 файл:

Вот его содержимое:

  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 настроена стандартно:

В закладке Debug - Settings - Flash Download необходимо выключить любую работу с Flash памятью:

Выключена загрузка Flash и в закладке Utilites:

Проверка примера

Результат работы примера представлен на картинке ниже. В окне Call Stack видны значения переменных и результаты математических операций. В окне дизассемблера виден получившийся код. Он значительно отличается от кода без использования FPU.

prog/spec/fpu_ve8.txt · Последние изменения: 2018/07/23 17:16 — katya