Jump to content
    

Универсальный порт для Cortex-Mx (GCC) залит в репозиторий.

Тем не менее, боевой проект собрался компилятором 5.4 2016q3 (windows, скачан с arm.com) с галкой LTE и успешно работает.

6-я версия тоже работает, но требует некрасивых танцев вокруг шаблонов.

 

Да, ещё и на аналогичные грабли с таблицей векторов наступил.

 

 

PS что хорошо, размер бинарника уменьшился килобайт на 5. С учётом того, что свободного места у нас осталось впритык, идея LTO требует всяческого развития.

Share this post


Link to post
Share on other sites

Да, сейчас попробовал, смог собрать с LTO. Добавил __attribute__((used)) к os_context_switch_hook() и __init_system_timer(). Сложность в том, что os_context_switch_hook() объявлена в os_kernel.h, и для того, чтобы добавить к ней этот атрибут, придётся что-то придумывать для всех компиляторов и поддерживаемых контроллеров.

Надо будет попробовать всё же сделать *.S файл, возможно, это позволит обойтись без залезания в общий код оси.

 

А таблица векторов у меня давно уже с этим атрибутом.

Share this post


Link to post
Share on other sites

Можно просто в scmRTOS_TARGET.h добавить

 

extern "C" {
    extern stack_item_t* os_context_switch_hook(stack_item_t* sp)    __attribute__((used));
    extern void __init_system_timer()                                 __attribute__((used));
};

Share this post


Link to post
Share on other sites

Да, так компилируется, но выдаёт warning про "redundant redeclaration". Неаккуратно как-то.

 

Share this post


Link to post
Share on other sites

Для проверки вынес PendSV_Handler() в ассемблерный файл. Всё прекрасно собралось с LTE, без внесения изменений в общие файлы оси. Выигрыш на моём тестовом проекте небольшой, но есть (text/data):

  • без LTE (-02)...: 5948/468
  • с LTE (-02)......: 5704/464
  • без LTE (-0s)...: 5576/468
  • c LTE (-0s)......: 5536/464

Ещё чуть потестирую, и, наверное, залью в develop. Потому как от этого никакого вреда, окромя пользы :)

Share this post


Link to post
Share on other sites

Ещё чуть потестирую, и, наверное, залью в develop. Потому как от этого никакого вреда, окромя пользы :)

Залил в develop. Теперь LTE работает.

 

---

Проверил на небольшом проекте (text/data):

 

Без LTE: 25320 13956

...с LTE: 23432 13948

 

Неплохо.

Share this post


Link to post
Share on other sites

Поправьте, пожалуйста, название файла описания порта.

На данный момент осталось старое название файла scmRTOS.ru.CortexM3.GCC,

хотя внутри уже название корректное Cortex-M/GCC.

С уважением.

Share this post


Link to post
Share on other sites

Так этот документ только про M3. Это тогда надо и содержание править, а не только название. Когда появится время - обязательно займусь.

Share this post


Link to post
Share on other sites

GCC, scmRTOS v5.1.0, Cortex-M4F, -mfloat-abi=hard -mfpu=fpv4-sp-d16, FPU включен.

Обнаружился следующий косяк:

В файле os_target.cpp есть такие строчки:

uintptr_t sptr = (((uintptr_t)Stack - CONTEXT_SIZE) & 0xFFFFFFF8UL) + CONTEXT_SIZE;
StackPointer = (stack_item_t*)sptr;

Проблема в том, что для включенной аппаратной плавучке мы имеем CONTEXT_SIZE = 17 * sizeof(stack_item_t),

а значит мы получим не выровненный по 8-байтам указатель на начало стека процесса.

Далее функция init_stack_frame() модифицирует StackPointer, имитируя сохранение контекста, после чего StackPointer становится выровненным по 8-байтам (хотя это, кстати, не нужно).

Функция os_start() имитирует извлечение контекста первого процесса:

"    ADD     %[stack], #(4 * 17)       \n" // emulate context restore

(после чего мы снова получаем не выровненный по по 8-байтам указатель на стек процесса)

и записывает не выровненный указатель в PSP.

В результате мы входим в первый процесс с не выровненным по 8-байтам PSP. Компилятор об этом ничего не знает.

У меня это проявилось довольно не простым образом: не работала печать float переменных с помощью printf(), печаталось че попало. При этом, печать любых других величин работала корректно. Операции вычисления с float тоже работали корректно.

Решение:

заменить операцию выравнивания на 

uintptr_t sptr = (uintptr_t)Stack & 0xFFFFFFF8UL;

В этом случае в PSP всегда будет записываться выровненное значение.

А то, что StackPointer у спящего процесса будет не выровненным, так это не имеет значения, так как при пробуждении будет восстановлен контекст и он выровняется перед записью его в PSP.

Share this post


Link to post
Share on other sites

5 минут назад, injen-d сказал:

Проблема в том, что для включенной аппаратной плавучке мы имеем CONTEXT_SIZE = 17 * sizeof(stack_item_t),

А почему в scmRTOS сохраняются только 17 регистров FPU, а не все 33?

Или может всё-таки sizeof(stack_item_t) == 8 и тогда всё будет ок?  ;)

Share this post


Link to post
Share on other sites

3 minutes ago, jcxz said:

А почему в scmRTOS сохраняются только 17 регистров FPU, а не все 33?

Или может всё-таки sizeof(stack_item_t) == 8 и тогда всё будет ок?  ;)

регистры FPU сохраняются если использовались на момент переключения задач:

        "    TST       LR, #0x10         \n" // exc_return[4]=0? (it means that current process
        "    IT        EQ                \n" // has active floating point context)
        "    VSTMDBEQ  R0!, {S16-S31}    \n" // if so - save it.

stack_item_t равно 4 так как 1 item - это один регистр (4 байта)

Share this post


Link to post
Share on other sites

4 минуты назад, injen-d сказал:

регистры FPU сохраняются если использовались на момент переключения задач:

И что? Например - задача использовала все 32 регистра данных. Почему в контекст сохраняются только 16 из них?

И каким образом переключатель задач узнаёт о том, какие именно регистры использовались (в задаче), а какие - нет?

Share this post


Link to post
Share on other sites

11 minutes ago, jcxz said:

И что? Например - задача использовала все 32 регистра данных. Почему в контекст сохраняются только 16 из них?

И каким образом переключатель задач узнаёт о том, какие именно регистры использовались (в задаче), а какие - нет?

https://www.pjrc.com/teensy/beta/DDI0403D_arm_architecture_v7m_reference_manual.pdf

Вот здесь рассказано, что s0-s15 сохраняются автоматически, и как узнать, что FPU использовался на момент прерывания

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...