AHTOXA 18 31 марта, 2015 Опубликовано 31 марта, 2015 · Жалоба Всем привет. Добрался до 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. Замечания и предложения приветствуются:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 3 апреля, 2015 Опубликовано 3 апреля, 2015 · Жалоба Замечания и предложения приветствуются:) Ну раз так, то настало время спросить. startup.c: Почему бы не разогнать ядро, выполнив init_HW() до инициализации .bss и .data? Зачем нужен __attribute__((__interrupt__)) для void Reset_Handler(void)? В стандартных шаблонах от производителей этого нет. sysinit.cpp: Не кошернее ли enable IOPx peripheral делать не в общем для всех случаев файле, а на уровне конкретного проекта? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 3 апреля, 2015 Опубликовано 3 апреля, 2015 · Жалоба 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. Привычка к нормализации:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 11 апреля, 2015 Опубликовано 11 апреля, 2015 · Жалоба Обнаружил баг. Оказывается, Cortex-M0 не позволяет побайтовый доступ к регистрам System Control Block (SCB). Поэтому некорректно устанавливались приоритеты обработчиков прерываний PendSV и SysTick. Исправил в rev. 586. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба В более ранних версиях приоритеты обработчиков прерываний PendSV и SysTick устанавливались как SCB->SHPR3 = 0 | (3 << 22) // PendSV priority = 3, lowest | (2 << 30) // SysTick priority = 2, little higher ; Сейчас они устанавливаются одинаковыми, хоть и наинизшими. Есть какая-то причина? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Нет, какой-то особой причины нет. Просто я сделал так, как было в порте для M3/M4. Там всю дорогу были одинаковые (наинизшие) приоритеты для PendSV и SysTick. Я подумал, что у M0 приоритетов и так мало, и жалко тратить аж два уровня из них на ось. К тому же, инициализация SysTick сделана опциональной, так что пользователь всегда может написать свой вариант функции __init_system_timer(), в которой задаст нужный ему приоритет. А зачем может быть нужно, чтобы SysTick мог прерывать PendSV? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 (изменено) · Жалоба Я имел в виду другое. Возможно в более ранней версии для порта Cortex M0 была причина сделать так, чтобы PendSV могла быть вытеснена любым другим прерыванием, в том числе и SysTick. Об этом неплохо бы у Сергея Борща спросить ;) ПС: В порте для Cortex M3 приоритеты одинаковые. Изменено 16 апреля, 2015 пользователем IgorKossak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Да простая там идея - чтобы перепланировка выполнялась после всех прерываний, которые могут эту перепланировку потребовать. Чтобы не перепланировать дважды. Само прерывание перепланировки выполняется с запрещенными прерываниями и прервать его никто не может. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Ага, то есть, если за время обработки какого-нибудь более приоритетного прерывания взведутся флаги SysTick и PendSV, то, при одинаковых приоритетах, сначала сработает PendSV, и уже потом SysTick, который в свою очередь может взвести флаг PendSV. А если мы поднимем приоритет SysTick-а, то всё сработает как надо - сначала SysTick, и уже потом PendSV. Так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба А если мы поднимем приоритет SysTick-а, то всё сработает как надо - сначала SysTick, и уже потом PendSV. Так?Именно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба Тогда надо приподнять. Сделаю на днях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба Тогда надо приподнять. Сделаю на днях. Величины приоритетов сейчас задаются жёстко в файле OS_Target_cpp.cpp на уровне порта. Величина "приподнимания" в случае с Cortex M3/4 будет зависеть от параметра функции NVIC_SetPriorityGrouping(n), в функции void init_HW(void) в файле sysinit.cpp на уровне приложения. На мой взгляд такое распределение не очень удобно. Может лучше эти магические числа вынести куда-нибудь в scmRTOS_TARGET_CFG.h? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 18 апреля, 2015 Опубликовано 18 апреля, 2015 · Жалоба Нас не волнует группировка приоритетов, нам же не надо, чтобы 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, то оставляем старое поведение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 18 апреля, 2015 Опубликовано 18 апреля, 2015 · Жалоба То есть в порт добавляется еще куча объявлений уровня проекта. Зачем вообще пихать это все в ОСь? Достаточно попросить пользователя настроить эти два прерывания и системный таймер где, когда и как ему будет удобно. Я вообще делаю все настройки периферии в стартапе и мне совершенно не нужны эти определения. Более того, меня напрягает необходимость сейчас передавать в потроха ОСи значение тактовой частоты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 18 апреля, 2015 Опубликовано 18 апреля, 2015 · Жалоба Какая куча? Добавляется всего одно объявление, причём как раз на уровне проекта. А в порте - fallback для старых проектов, в которых нет этого объявления. Как здесь можно сделать иначе? Что касаемо вообще настройки таймера в порте, а не в проекте - так уж исторически сложилось. В ядре есть специальный таймер для оси, поэтому удобно иметь настройку этого таймера на уровне порта. Вот например, сейчас - выяснилось, что полезно иметь приоритет системного таймера чуть повыше, чем приоритет прерывания планировщика. Я исправлю порт, и все проекты, использующие этот порт, автоматически получат это исправление. Разве это не хорошо? Возможность выбрать другой таймер - есть. Возможность заменить функцию инициализации таймера на свою - тоже есть. Естественно, такого рода вариативность требует некоторых телодвижений, типа задания значение тактовой частоты. Я думаю, что это небольшая плата за гибкость. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться