|
|
  |
Выпущена scmRTOS 4.0., Ура, товарищи! :) |
|
|
|
May 2 2012, 05:33
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
QUOTE (AHTOXA @ May 2 2012, 01:33)  Да, это особенность портов для Cortex-M3. Специальный таймер в ядре - грех было не использовать. Теперь понимаю, что это не всегда удобно. Совсем выносить настройку прерывания на уровень проекта очень неохота - придётся дописывать инициализацию во все имеющиеся проекты. Идея с WEAK мне кажется более подходящей. Постараюсь на днях опробовать этот вариант. Для того, чтобы подменить таймер, достаточно, как я понимаю, указать другой ISR. Т.е. даже в имеющейся реализации можно написать просто свой обработчик прерываний по образу и подобию в проекте, а ISR таймера ядра залочить. Ничего в сорцах ОС править не надо. Поправь, если ошибаюсь.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 2 2012, 08:40
|

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

|
Всё ещё проще!  Для переопределения источника прерывания надо всего лишь передвинуть обработчик SystemTimer_ISR в таблице векторов и дописать инициализацию. Это в случае, если устраивает имеющийся обработчик. Если не устраивает (например, надо в обработчике сбрасывать флаг прерывания), то делаем так (пример для TIM2 в STM32): 1. В таблице векторов прерываний переименовываем SystemTimer_ISR во что-то другое (чтобы не вызывался штатный осёвый обработчик); 2. В scmRTOS_TARGET_CFG.h дописываем: Код namespace OS { extern "C" void TIM2_IRQHandler(); } 3. Где-то в проекте вписываем новый обработчик: Код extern "C" void OS::TIM2_IRQHandler() { if (TIM2->SR & TIM_SR_UIF) { scmRTOS_ISRW_TYPE ISR; TIM2->SR = ~TIM_SR_UIF;
Kernel.system_timer();
#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 system_timer_user_hook(); #endif } } 4. Где-то до запуска run() инициализируем этот таймер (не забываем назначить ему наименьший приоритет!). Вроде всё
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 3 2012, 12:35
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(AHTOXA @ May 2 2012, 11:40)  Вроде всё  «Та не»™ Надо еще выключить инициализацию SYSTICK (включение таймера и разрешение его прерываний) в os_start, которая в OS_Target_asm.S сидит. Так что таки надо какой-то #define scmRTOS_CM3_PORT_USER_SYSTICK в scmRTOS_TARGET_CFG.h. Поскольку это касается исключительно этого порта, стоит ли в scmRTOS_defs.h вносить проверку?
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 3 2012, 12:49
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
QUOTE (ReAl @ May 3 2012, 19:35)  «Та не»™ Надо еще выключить инициализацию SYSTICK (включение таймера и разрешение его прерываний) в os_start, которая в OS_Target_asm.S сидит.
Так что таки надо какой-то #define scmRTOS_CM3_PORT_USER_SYSTICK в scmRTOS_TARGET_CFG.h. Поскольку это касается исключительно этого порта, стоит ли в scmRTOS_defs.h вносить проверку? А можно и не выносить, а просто вырубить в main. Пара инструкций никому плохо не сделает. Мне кажется, что нормальное решение - для подавляющего большинства проектов годится вариант, который по умолчанию в порте, а для тех редких случаев, где хочется заменить системный таймер на другой, это решается несколькими командами на уровне проекта.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 3 2012, 18:18
|

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

|
Цитата(ReAl @ May 3 2012, 18:35)  «Та не»™ Надо еще выключить инициализацию SYSTICK (включение таймера и разрешение его прерываний) в os_start, которая в OS_Target_asm.S сидит. Да пусть молотит, он нам не мешает, поскольку мы переименовали обработчик его прерывания. Если не нужен - потом в наиболее приоритетной задаче при старте отрубить, и всё. В общем, корявенько, но возможно  Цитата(Сергей Борщ @ May 3 2012, 23:27)  Так может быть вынести ее оттуда, как и в остальных портах? Вот этого делать очень неохота - придётся дописывать эту инициализацию в кучу проектов. Надо как-то придумать, чтоб по умолчанию было поведение как сейчас. Какой-нибудь WEAK start_systimer(), что ли. Ну или Цитата(ReAl @ May 3 2012, 18:35)  какой-то #define scmRTOS_CM3_PORT_USER_SYSTICK в scmRTOS_TARGET_CFG.h.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 3 2012, 19:27
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(AHTOXA @ May 3 2012, 21:18)  Да пусть молотит, он нам не мешает, поскольку мы переименовали обработчик его прерывания. Что-то я не понял. Прерывание-то разрешено в регистрах NVIC. Цитата 1. В таблице векторов прерываний переименовываем SystemTimer_ISR во что-то другое (чтобы не вызывался штатный осёвый обработчик); Без обработчика влетит в Default_Handler()Тут разве что это «что-то другое» состоит из функции, запрещающей назад прерывание, сбрасывая NVIC_ST_CTRL_INTEN. ------------------------------------- Цитата(_Артём_ @ Apr 10 2012, 17:11)  Все прерывания с приоритетом выше configKERNEL_INTERRUPT_PRIORITY не запрещаются никогда, но работают без использования ОСи. NVIC CM3 позволяет сделать подобное. Но есть ли в этом смысл? Или оно не надо никому? https://groups.google.com/group/scmrtos-ru/...c21f94515?hl=ru
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 4 2012, 04:48
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
QUOTE (_Артём_ @ May 4 2012, 08:10)  Пришла такая мысль: CODE class TCritSect { public: TCritSect () { // запрет всех прерываний } #if (scmRTOS_USER_DEFINED_CRITSECT_ENABLE==1) TCritSect(enum INT_PRIORITY level) { // запрет всех кроме указанных }; #endif ~TCritSect() { // восстановление в изначальное состояние }
private: enabled_level_t EnabledLevels; }; И как это поможет? Этим можно пилотировать в своём коде, который пишется в данный момент. Но критические секции в коде ОС останутся без изменений. По поводу таймера. Мне казалось, что самым правильным решением было бы не завязываться на аппаратуру таймера в коде ОС и вынести всю инициализацию на уровень проекта. Там реально несколько строчек. Зато никаких вопросов не возникает. Я так и делал в порте для Blackfin'а, хотя там тоже есть специальный таймер в ядре. Как сейчас правильнее поступить, даже не знаю.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 4 2012, 05:53
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(_Артём_ @ May 4 2012, 04:10)  Код #if (scmRTOS_USER_DEFINED_CRITSECT_ENABLE==1) TCritSect(enum INT_PRIORITY level) { // запрет всех кроме указанных }; #endif Во-первых, как уже написал Гарри, запрещающий все конструктор без аргументов ничего не поменяет в работе ОС, а это была цель. Во-вторых, этот enum у всех будет свой (у Cortex оно вообще от проекта к проекту реально плавать будет). Где-то там в обсуждениях в группе я об этом писал — «стандартизовать» можно максимум имя для этого enum. Так что сейчас надо просто в scmRTOS_TARGET_CFG.h написать: Код #define scmRTOS_USER_DEFINED_CRITSECT_ENABLE 1 // как нужно автору проекта в данном проекте enum TIsrPriority { ipNone = ..., ipXXX = ..., ipYYY = ..., ipAll = ... };
const TIsrPriority ipOsLevel = ipXXX;
class TCritSect { public: // и TCritSect cs в ОС отработает с этим уровнем. TCritSect(TIsrPriority level = ipOsLevel) { // запрет всех кроме указанных }; ... }; Для STM8, к примеру, можно и сразу в порте так сделать, там число уровней фиксировано. Только - enum нужно в OS_Target.h определить выше включения scmRTOS_TARGET_CFG.h
- Дабы не плодить #define/#ifdef — константу const TIsrPriority ipOsLevel обязать задавать в scmRTOS_TARGET_CFG.h
- Сам такой «приоритетный» класс задать в OS_Target.h определить ниже включения scmRTOS_TARGET_CFG.h.
Но пока это не сделано, каждый может подсунуть своё (у меня с портом STM8 вообще пауза — и у меня времени нет, и тот, кто попросил порт сделать — свою дискавери-платку забрал назад  ).
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|