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

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

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

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

 

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

 

 

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

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


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

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

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

 

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

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


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

Можно просто в 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));
};

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


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

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

 

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


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

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

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

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

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


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

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

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

 

---

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

 

Без LTE: 25320 13956

...с LTE: 23432 13948

 

Неплохо.

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


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

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

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

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

С уважением.

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


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

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

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


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

Moderator: Про перенос векторов теперь тут - https://electronix.ru/forum/index.php?showtopic=146314

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


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

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.

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


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

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

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

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

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

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


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

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 байта)

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


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

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

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

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

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

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


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

11 minutes ago, jcxz said:

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

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

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

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

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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