реклама на сайте
подробности

 
 
6 страниц V  < 1 2 3 4 5 > »   
Reply to this topicStart new topic
> Cortex-M4(F) порт под GCC залит в репозиторий.
сарматъ
сообщение Aug 15 2013, 09:09
Сообщение #31


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



Цитата(AHTOXA @ Aug 15 2013, 11:16) *
и затем в коде помещаем нужные переменные в секцию .battram:
Код
nvBuffer[128]  __attribute__((__section__(".battram")));

Теперь буфер nvBuffer будет расположен в батареечной памяти.


огромное спасибо!!

Цитата(AHTOXA @ Aug 15 2013, 11:16) *
Во-первых, файл stm32f4xx.h не используется собственно осью, только примерами.
А во-вторых, это и есть стандартный stm-овский файлsm.gif (он у меня был расположен в "Libraries/CMSIS/ST/STM32F4xx/Include").
В общем, если есть другой, более полный файл, просто используйте его, и всё.


все заработало

в версии stm32f4xx.h 2013 года учитываются разные контр и соотв существует два разных дефайна
STM32F427X и STM32F40XX, соотв чтобы с этим файлом корректно работала ось необходимо
- в майк файле добавить SUBCHIP = STM32F40XX, изменить DEFS = -D$(CHIP) на DEFS = -D$(SUBCHIP)
- в pin.h #if (defined STM32F2XX) || (defined STM32F4XX) заменить на
#if (defined STM32F2XX) || (defined STM32F4XX) || (defined STM32F40XX) || (defined STM32F427X)

больше в файлах оси я не нашел вхождений константы STM32F4XX, вопрос: их действительно бальше нет или я просто не нашел?

Сообщение отредактировал сарматъ - Aug 15 2013, 18:35
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 16 2013, 09:58
Сообщение #32


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(сарматъ @ Aug 15 2013, 15:09) *
в версии stm32f4xx.h 2013 года учитываются разные контр и соотв существует два разных дефайна
STM32F427X и STM32F40XX

Я не видел этого вашего ответа, и поэтому решил-таки сделать пример с использованием ST-lib.
Сейчас собрался его запостить, а у вас уже всё решилосьsm.gif
Но. В только что мной скачанной версии stm32f4xx.h (11-January-2013) уже есть три дефайна:
Код
#if !defined (STM32F4XX) && !defined (STM32F40XX) && !defined (STM32F427X)

Поэтому мне не пришлось править makefile, прокатил имеющийся дефайн STM32F4XX.
Хотя может быть, я просто что-то не так понял в организации библиотекиsm.gif
Цитата(сарматъ @ Aug 15 2013, 15:09) *
больше в файлах оси я не нашел вхождений константы STM32F4XX, вопрос: их действительно бальше нет или я просто не нашел?

Действительно нет. Ось использует для определения архитектуры M3-M4/M4F дефайн __SOFTFP__, остальное ей неважно.
Ладно, всё равно выложу пример, раз уж сделал. Может кому-ннибудь пригодится sm.gif
Вот: Прикрепленный файл  6_ST_libs.zip ( 459.93 килобайт ) Кол-во скачиваний: 108


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 16 2013, 10:16
Сообщение #33


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



Цитата(AHTOXA @ Aug 16 2013, 12:58) *
Но. В только что мной скачанной версии stm32f4xx.h (11-January-2013) уже есть три дефайна:
Код
#if !defined (STM32F4XX) && !defined (STM32F40XX) && !defined (STM32F427X)


они пошутилиwink.gif на самом деле если использовать STM32F4XX то не будет определено перывание FPU, поэтому надо использовать либо STM32F40XX либо STM32F427X (на сколько я разобрался в stm32f4xx.h)

кстати как интересно то в сисинит...

#if (!defined __SOFTFP__)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); // set CP10 and CP11 to all ones.
#endif

по логике должно включаться если не эмулируется плавающая точка и есть вычисления с ней - то есть аппаратная плавающая арифметика, НО она может не эмулироваться и в CM3 - скажем, когда в задачке только целочисленная арифметика, думаю все же правильнее было бы сделать как в оригинале

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif

да.. и видимо так же правильнее было бы откорректировать ос_таргет_сипипи - для CM3 если не определена эмуляция плавающей точки порт будет работать как для процессоров с аппаратной плавающей арифметикой

как понимаю __VFP_FP__ и __SOFTFP__ устанавливаются компилятором в зависимости от вот этой строчки майк файла FPU= -mfpu=fpv4-sp-d16 -mfloat-abi=hard, правильно? а далее __FPU_PRESENT и __FPU_USED устанавливаются соотв в stm32xx.h и core_cm4.h и далее ими уже пользуются все остальные модули программы, так?

Сообщение отредактировал сарматъ - Aug 16 2013, 11:38
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 16 2013, 14:43
Сообщение #34


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(сарматъ @ Aug 16 2013, 16:16) *
они пошутилиwink.gif на самом деле если использовать STM32F4XX то не будет определено перывание FPU, поэтому надо использовать либо STM32F40XX либо STM32F427X (на сколько я разобрался в stm32f4xx.h)

Наверное да, STM32F4XX - это общий дефайн для семейства, а STM32F40XX и STM32F427X - это варианты исполнения.
Прерывание FPU есть в обоих вариантах, так что можно просто перенести его в общую часть:
Код
  CRYP_IRQn                   = 79,     /*!< CRYP crypto global interrupt                                      */
  HASH_RNG_IRQn               = 80,      /*!< Hash and Rng global interrupt                                     */
  FPU_IRQn                    = 81      /*!< FPU global interrupt                                              */
#ifdef STM32F427X
  ,
  UART7_IRQn                  = 82,     /*!< UART7 global interrupt                                            */

Цитата(сарматъ @ Aug 16 2013, 16:16) *
кстати как интересно то в сисинит...

#if (!defined __SOFTFP__)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); // set CP10 and CP11 to all ones.
#endif

по логике должно включаться если не эмулируется плавающая точка и есть вычисления с ней - то есть аппаратная плавающая арифметика, НО она может не эмулироваться и в CM3 - скажем, когда в задачке только целочисленная арифметика, думаю все же правильнее было бы сделать как в оригинале

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif

sysinit.cpp - это просто пример, это не часть порта/оси. Поэтому он не претендует на универсальность. Он сделан просто для примера. К тому же, __SOFTFP__ - это дефайн компилятора, а __FPU_PRESENT и __FPU_USED - это дефайны из ST-шной библиотеки, а она в примерах не использовалась.
Цитата(сарматъ @ Aug 16 2013, 16:16) *
да.. и видимо так же правильнее было бы откорректировать ос_таргет_сипипи - для CM3 если не определена эмуляция плавающей точки порт будет работать как для процессоров с аппаратной плавающей арифметикой

Не, там всё нормально. Вот тут я выяснял самый подходящий дефайн. Получилось, что это __SOFTFP__. (__VFP_FP__ определён во всех четырёх случаях, так что его проверять нет смысла.)
Цитата(сарматъ @ Aug 16 2013, 16:16) *
как понимаю __VFP_FP__ и __SOFTFP__ устанавливаются компилятором в зависимости от вот этой строчки майк файла FPU= -mfpu=fpv4-sp-d16 -mfloat-abi=hard, правильно? а далее __FPU_PRESENT и __FPU_USED устанавливаются соотв в stm32xx.h и core_cm4.h и далее ими уже пользуются все остальные модули программы, так?

Я не особо разбираюсь в ST-шных либах. По-моему, там жёстко задаётся __FPU_PRESENT = 1, а __FPU_USED устанавливается в зависимости от __VFP_FP__ и __SOFTFP__.
Кстати, поэтому варианты
Код
#if (!defined __SOFTFP__)

и
Код
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

идентичныsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 16 2013, 18:37
Сообщение #35


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



короче сломал себе голову и сделал проще, вот так в мейкфайле


CHIP = STM32F4XX
HSE_VALUE = 8000000

ifeq ($(CHIP),STM32F4XX)
MCU = cortex-m4
FPU = -mfpu=fpv4-sp-d16 -mfloat-abi=hard
#FPU = -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
DEFS = -DSTM32F40XX
else
MCU = cortex-m3
DEFS = -D$(CHIP)
DEFS += -DST_M___3__2_C__M_3__SOFTFP__
endif

# compiler defines
DEFS += -DVER_MAJOR=$(VER_MAJOR)

ну и в порте заменил __SOFTFP__ на ST_M___3__2_C__M_3__SOFTFP__

Сообщение отредактировал сарматъ - Aug 17 2013, 13:53
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 17 2013, 20:53
Сообщение #36


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(сарматъ @ Aug 17 2013, 00:37) *
ну и в порте заменил __SOFTFP__ на ST_M___3__2_C__M_3__SOFTFP__

А зачем?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 18 2013, 09:05
Сообщение #37


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



Цитата(AHTOXA @ Aug 17 2013, 23:53) *
А зачем?


чтобы от меня зависело а не от компилятора(поставит он нужный дефайн или нет) как сохранять контекст как см3 или см4, этот дефайн в мейкфайле просто признак того что контроллер см3 wink.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 18 2013, 12:56
Сообщение #38


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Компилятор ставит дефайн __SOFTFP__ в двух случаях:
  • -mcpu=cortex-m3
  • -mcpu=cortex-m4

То есть, в случае M3 и M4 без сопроцессора. В этих случаях порт использует контекст M3.
В случае наличия сопроцессора (два варинта):
  • -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
  • -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp

используется контекст с плавучкой.
То есть, мы полностью управляем поведением порта: хотим M3 - определяем -mcpu=cortex-m3, хотим M4 без плавучки - определяем -mcpu=cortex-m4. Нужна плавучка - -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi={hard|softfp}.
Ну а если всё же хочется определить именно M3, то для этого у компилятора есть специальный дефайн: __ARM_ARCH_7M__
(для M4: __ARM_ARCH_7EM__).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 18 2013, 14:40
Сообщение #39


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



а как кстати определить адрес функции во флеше?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 18 2013, 15:40
Сообщение #40


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Что вы подразумеваете под "определить"? Если узнать адрес - в программе достаточно присвоить имя функции соответствующему указателю, а человеку нужно найти эту функцию в .map или дизассемблированном листинге. Если же вы имели ввиду "задать конкретный адрес для функции" - то надо в скрипте линкера описать секцию по нужному адресу и разместить фукцию в эту секцию при помощи __attribute__((section("имя секции"))


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 18 2013, 16:17
Сообщение #41


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



я имею ввиду написание загрузчика-биоса отдельно от прикладной программы, биос во флеше, прикладная программа во внешней ram(памяти оперативной все же не хватает)

то есть надо вначале компилировать биос и смотреть его мап файл потом прикладную программу и ее мап файл смотреть?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 18 2013, 16:26
Сообщение #42


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (сарматъ @ Aug 18 2013, 18:17) *
я имею ввиду написание загрузчика-биоса отдельно от прикладной программы
Все расно не понял, что же вам нужно - узнать адрес функции или разместить ее по заранее определенному адресу.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 18 2013, 16:31
Сообщение #43


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



узнать, т.е. загрузчик-биос загружает из внешней пзу прикладную программу в рам, потом вызывает функции из прикладной программы, которые в свою очередь могут вызывать функции из биоса
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Aug 19 2013, 12:07
Сообщение #44


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



восстановил задачку, все работает

очень приятное впечатление и от оси и от порта, спасибо разработчикам
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 19 2013, 13:24
Сообщение #45


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (сарматъ @ Aug 18 2013, 18:31) *
потом вызывает функции из прикладной программы, которые в свою очередь могут вызывать функции из биоса
В этом случае вам надо либо размещать эти функции по фиксированным адресам, что неудобно - либо будут оставаться дырки между ними, либо после очередного улучшения какая-то из функций не влезет в выделенную ей область и начнутся пляски по ее утаптыванию. Простое и надежное решение - разместите в приложении по фиксированному адресу таблицу указателей на функции и обращайтесь из загрузчика к функциям приложения через эту таблицу. Аналогичную таблицу указателей на функции загрузчика расместите по фиксированному адресу в загрузчике и обращайтесь через нее из приложения. Будет некий аналог таблицы векторов прерываний. Эти таблицы можно оформить в виде структур с осмысленными именами членов и даже добавить в эти структуры какие-то служебные данные, как, например, номер версии софта в приложении или номер версии железа в загрузчике:
CODE
// boot_cross.h
struct bootloader_cross_table
{
    uint8_t HW_version;
    void (* func1)();
    uint8_t (* func2)();
    uint32_t (* func3)(uint32_t param);
};

// bootloader.cpp
#include    "boot_cross.h"
__attribute__((section(".text.boot.cross_table")))
bootloader_cross_table Cross_table =
{
    1,
    boot_func_1,
    boot_func_2,
    boot_func_3,
};

// application.cpp
#include    "../bootloader/boot_cross.h"
extern bootloader_cross_table Bootloader;   // а в скрипте линкера добавить PROVIDE(Bootloader = абсолютный адрес);
                                            // или же в командной строке линковки добавить -Wl,--defsym,Bootloader=адрес

void test()
{
    printf("Hardware version: %d", Bootloader.HW_version);
    
    Bootloader.func1();
    uint32_t Data = Bootloader.func3(12345);
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

6 страниц V  < 1 2 3 4 5 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 02:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.0152 секунд с 7
ELECTRONIX ©2004-2016