Перейти к содержанию
    

Настройка GCC компилятора для CortexM4

Здравствуйте, уважаемые форумчане. Пытаюсь настроить GCC компилятор для работы с STM32F4. Нашел на сайте gcc что для оптимального использования инструкций процессора необходимо задать ключ -mtune со следующими атрибутами: -mtune=arm7m. STM32F4 (Cortex-M4) выполнен архитектуре ARMv7E-M и поддерживает DSP инструкции. А ключ -mtune=arm7m относится к процессорам Cortex-M3 (архитектура ARMv7-M) - которые не поддерживают DSP. Кто знает какой атрибут ключа должен быть задан для ARMv7E-M?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

-mcpu=cortex-m4 -mthumb -c -Os -std=c99 -Wall -Wl,--gc-sections -Wno-psabi -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-

 

( h..p://code.google.com/p/yus-repo/downloads/detail?name=lm4f-gcc-arm-ide-win32.7z )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По-моему это не серьезно. Компилятор, если ему указать, должен сам подставлять нужные инструкции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сравнивал два компилятора GCC 4.7 и ARMCC 4.1.0 в Keil'e. Код вида i+=a*a эти компиляторы исполняют по разному. В ARMCC это выглядит следующим образом:

post-41333-1372827356_thumb.jpg

т.е. используется одна команда MLA ( Multiply with accumulate).

А GCC делает этот код следующим образом:

post-41333-1372827519_thumb.jpg

сначала mul (умножение) потом adds (add with substract).

Т.е. команд в GCC становится на 3 больше. Вопрос можно ли заставить gcc использовать такие же инструкции как и в ARMCC. (MLA не DSP инструкция).

Уровни оптимизации одинаковые -O0

Изменено пользователем sidy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уровни оптимизации одинаковые -O0
gcc сделал именно то, что вы просили - сначала умножил, потом прибавил. И без всякой самодеятельности, ибо оптимизацию вы ему запретили. Попробуйте -Os, -O3, тогда можно будет что-то сравнивать.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задам еще один вопрос: сейчас использую CooCox CoIDE и программа сваливается в заглушку Default Handler. И я не знаю как посмотреть стэк (и можно ли это вообще сделать) в CoIDE. В Keil это можно было сделать - там был stack view, в котором видно, какая функция вызывалась последней. Есть ли такая возможность в CoIDE? И если нет, то как выяснять откуда попадаем в Default Handler?

Изменено пользователем sidy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прочитать наконец доку на используемое ядро.

Посмотреть содержимое LR. По нему определить стек возврата (PSP или MSP). Прочитать 8 слов с этого стека.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот я снова получил Default Handler:

post-41333-1386307239_thumb.jpg

в LR содержится 0xFFFFFFF1, но прочитав документ Cortex M4 programming manual не нашел как по содержимому LR определить стек возврата MSP или PSP.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Невнимательно вы читали. Раздел "Exception model", пункт 2.3.7 "Exception entry and return", таблица 18. Это если речь идет о документе от ST "STM32F3xxx and STM32F4xxx Cortex-M4 programming manual". Если у вас другой - дайте полное название или ссылку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

GCC не умет???????????????

 

c-код

  NOP();
  NOP();
  NOP();
  i+=a*b;
  NOP();
  NOP();
  NOP();

 

 

ключи -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -Os -fomit-frame-pointer -finline-functions -ffunction-sections -fdata-sections -fgraphite -funroll-loops -flto=8

 

выход компиллера

 80016d0:    bf00          nop
  NOP();
80016d2:    bf00          nop
  NOP();
80016d4:    bf00          nop
  i+=a*b;
80016d6:    4f59          ldr    r7, [pc, #356]; (800183c <ResetHandler.4045+0x880>)
80016d8:    4b59          ldr    r3, [pc, #356]; (8001840 <ResetHandler.4045+0x884>)
80016da:    680e          ldr    r6, [r1, #0]
80016dc:    6818          ldr    r0, [r3, #0]
80016de:    683a          ldr    r2, [r7, #0]
80016e0:    fb00 2406     mla    r4, r0, r6, r2
80016e4:    603c          str    r4, [r7, #0]
  NOP();
80016e6:    bf00          nop
  NOP();
80016e8:    bf00          nop
  NOP();
80016ea:    bf00          nop

 

под четверку тем более....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в LR содержится 0xFFFFFFF1, но прочитав документ Cortex M4 programming manual не нашел как по содержимому LR определить стек возврата MSP или PSP.

 

Читать надо документацию на архитектуру в целом. Конкретно по прерывания можно на русском посмотреть здесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как написано в ReferenceManual во время исключения в LR записывается значение EXC_RETURN. У меня в LR записано 0xFFFFFFF1. Как написано в RM такое значение появляется при: Return to Handler mode, exception return uses non-floating-point state from the MSP and execution uses MSP after return. Т.е. теперь мне необходимо в DefaultHandler прочитать MSP следующим образом: uint32_t i=__get_MSP(), и в i будет содержаться адрес с которого программа попадает в HardFault. Правильно ли я понял?

Изменено пользователем sidy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как написано в ReferenceManual во время исключения в LR записывается значение EXC_RETURN. У меня в LR записано 0xFFFFFFF1. Как написано в RM такое значение появляется при: Return to Handler mode, exception return uses non-floating-point state from the MSP and execution uses MSP after return. Т.е. теперь мне необходимо в DefaultHandler прочитать MSP следующим образом: uint32_t i=__get_MSP(), и в i будет содержаться адрес с которого программа попадает в HardFault. Правильно ли я понял?

 

Вот код стыбренный на просторах интернета (на форуме st) для Cortex M3:

 

 

   void hard_fault_handler_c(unsigned int * hardfault_args)
{
  unsigned int stacked_r0;
  unsigned int stacked_r1;
  unsigned int stacked_r2;
  unsigned int stacked_r3;
  unsigned int stacked_r12;
  unsigned int stacked_lr;
  unsigned int stacked_pc;
  unsigned int stacked_psr;

  stacked_r0 = ((unsigned long) hardfault_args[0]);
  stacked_r1 = ((unsigned long) hardfault_args[1]);
  stacked_r2 = ((unsigned long) hardfault_args[2]);
  stacked_r3 = ((unsigned long) hardfault_args[3]);

  stacked_r12 = ((unsigned long) hardfault_args[4]);
  stacked_lr = ((unsigned long) hardfault_args[5]);
  stacked_pc = ((unsigned long) hardfault_args[6]);
  stacked_psr = ((unsigned long) hardfault_args[7]);

  printf ("[Hard fault handler]\n");
  printf ("R0 = %x\n", stacked_r0);
  printf ("R1 = %x\n", stacked_r1);
  printf ("R2 = %x\n", stacked_r2);
  printf ("R3 = %x\n", stacked_r3);
  printf ("R12 = %x\n", stacked_r12);
  printf ("LR = %x\n", stacked_lr);
  printf ("PC = %x\n", stacked_pc);
  printf ("PSR = %x\n", stacked_psr);
  printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
  printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
  printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
  printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
  printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));


  while (1);

}


/*******************************************************************************
* Description : This function handles Hard Fault exception.
* Input       : -
* Return      : -
*******************************************************************************/
void HardFault_Handler(void)
{
    // Go to infinite loop when Hard Fault exception occurs
  asm("TST LR, #4");
  asm("ITE EQ");
  asm("MRSEQ R0, MSP");
  asm("MRSNE R0, PSP");
  asm("B hard_fault_handler_c");
    while (1);
}

 

Доработaть по вкусу.

printf можно выбросить.

Поставить брейкпойнт на месте первого printf.

Сравнить пойманный аддресс с map файлом, найти из какой функции вылетает

 

Может, memory corruption или stack маленький.

Наиболее частые проблемы, мне кажется, особенно при таких странных LR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я снова получил HardFault и использовал функцию, приведенную выше для определения адреса с которого перешли в HardFault. Значения переменных у меня получились следующие:

post-41333-1387351757.jpg

А значения регистров в отладчике такие:

post-41333-1387351786_thumb.jpg

Вопрос почему несовпадают значения r0, r1, r2, r3 и т.д. полученные в функции с тем что я вижу в регистрах? И как теперь мне определить адрес из которого попали в HardFault?

И еще мысль переменные stacked_r0 и т.д. должны быть глобальными, чтобы не портить стэк?

 

И еще в Reference Manual написано что нужно использовать функции __get_PSP() и __get_MSP(), но когда я их пытаюсь вызвать компилятор выдает следующую ошибку:

[cc] C:\ARTRON_VER1.1\cmsis/core_cmFunc.h:410:61: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__get_PSP'

[cc] C:\ARTRON_VER1.1\cmsis/core_cmFunc.h:410:1: error: unknown type name '__STATIC_INLINE'

Сама функция в core_cmFunc.h описана так:

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)

{

register uint32_t result;

 

__ASM volatile ("MRS %0, psp\n" : "=r" (result) );

return(result);

}

Что нужно сделать чтобы данные функции вызывались нормально.

 

P.S. проверил в файле main.c функция __get_MSP(); вызывается, а вот в файле startup_stm32f4xx.c компилирует с ошибками, непонятно.

Изменено пользователем sidy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...