|
Универсальный порт для Cortex-Mx (GCC) залит в репозиторий. |
|
|
|
Mar 31 2015, 19:03
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Всем привет. Добрался до Cortex-M0+ (STM32L0xx). Подумал, что отличий от порта для Cortex-M4(F) немного, и поэтому взял порт Cortex-M0 от Сергея Борща и влил его в M4(F). А так как порт Cortex-M4(F) уже поддерживал Cortex-M3, то порт получился универсальный. Назвал порт CortexMx, чтоб не трогать имеющиеся. Поддерживаются Cortex-M3, Cortex-M4(F), Cortex-M0, Cortex-M0+, Cortex-M1. Добавил также пример для STM32L0xx (плата STM32 NUCLEO-L053R8). Планирую после тестирования перевести на этот порт все примеры для M3/M4. Замечания и предложения приветствуются
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 3 2015, 09:24
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Цитата(IgorKossak @ Apr 3 2015, 13:45) startup.c: Почему бы не разогнать ядро, выполнив init_HW() до инициализации .bss и .data? Дело в том, что в общем случае в init_HW() могут использоваться какие-нибудь статические/глобальные переменные, и тогда они будут использованы до инициализации. Если в вашем init_HW() гаранированно не нужны такие переменные, то можно и разогнать. Цитата Зачем нужен __attribute__((__interrupt__)) для void Reset_Handler(void)? В стандартных шаблонах от производителей этого нет. Это из каких-то совсем старых версий тянется, там было. Ни на что не влияет, можно смело убирать. Цитата sysinit.cpp: Не кошернее ли enable IOPx peripheral делать не в общем для всех случаев файле, а на уровне конкретного проекта? Так это и есть уровень проекта. Просто в примерах (когда их больше одного, как в STM32F1XX) файлы startup.c и sysinit.cpp совпадали, вот я их и вынес в папку SamplesCommon. Привычка к нормализации
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 11 2015, 09:24
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Обнаружил баг. Оказывается, Cortex-M0 не позволяет побайтовый доступ к регистрам System Control Block (SCB). Поэтому некорректно устанавливались приоритеты обработчиков прерываний PendSV и SysTick. Исправил в rev. 586.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 16 2015, 18:01
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Нет, какой-то особой причины нет. Просто я сделал так, как было в порте для M3/M4. Там всю дорогу были одинаковые (наинизшие) приоритеты для PendSV и SysTick. Я подумал, что у M0 приоритетов и так мало, и жалко тратить аж два уровня из них на ось. К тому же, инициализация SysTick сделана опциональной, так что пользователь всегда может написать свой вариант функции __init_system_timer(), в которой задаст нужный ему приоритет. А зачем может быть нужно, чтобы SysTick мог прерывать PendSV?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 16 2015, 18:58
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Ага, то есть, если за время обработки какого-нибудь более приоритетного прерывания взведутся флаги SysTick и PendSV, то, при одинаковых приоритетах, сначала сработает PendSV, и уже потом SysTick, который в свою очередь может взвести флаг PendSV. А если мы поднимем приоритет SysTick-а, то всё сработает как надо - сначала SysTick, и уже потом PendSV. Так?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 18 2015, 05:51
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Нас не волнует группировка приоритетов, нам же не надо, чтобы SysTick вытеснял PendSV, нам надо лишь, чтобы при одновременно установленных флагах этих прерываний первым срабатывало прерывание от SysTick. Для этого достаточно приподнять приоритет (или субприоритет) SysTick-а на 1 (== обнулить самую младшую значащую единичку в двоичном представлении приоритета). А вот с поиском позиции этой самой младшей значащей единички - надо будет подумать. Насколько я помню, число значащих бит приоритета зависит от реализации, а значит, его надо задавать на уровне проекта. К тому же, не хочется ломать совместимость с существующими проектами. Поэтому придётся добавтить в порт какие-то значения по умолчанию для каждой архитектуры. --- Думаю сделать как-то так: В scmRTOS_TARGET_CFG.h: Код #define CORE_PRIORITY_BITS 2 и в OS_Target_cpp.cpp: Код #if (!defined CORE_PRIORITY_BITS) # define SYS_TIMER_PRIO (0xFF) #else # define SYS_TIMER_PRIO (0xFE << (8-(CORE_PRIORITY_BITS))) #endif То есть, если не задано CORE_PRIORITY_BITS, то оставляем старое поведение.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 18 2015, 10:08
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Какая куча? Добавляется всего одно объявление, причём как раз на уровне проекта. А в порте - fallback для старых проектов, в которых нет этого объявления. Как здесь можно сделать иначе? Что касаемо вообще настройки таймера в порте, а не в проекте - так уж исторически сложилось. В ядре есть специальный таймер для оси, поэтому удобно иметь настройку этого таймера на уровне порта. Вот например, сейчас - выяснилось, что полезно иметь приоритет системного таймера чуть повыше, чем приоритет прерывания планировщика. Я исправлю порт, и все проекты, использующие этот порт, автоматически получат это исправление. Разве это не хорошо? Возможность выбрать другой таймер - есть. Возможность заменить функцию инициализации таймера на свою - тоже есть. Естественно, такого рода вариативность требует некоторых телодвижений, типа задания значение тактовой частоты. Я думаю, что это небольшая плата за гибкость.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|