реклама на сайте
подробности

 
 
> scmRTOS для начинающего., Очередное начало очередного начинающего :(
Beginning
сообщение Apr 28 2010, 15:13
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 511
Регистрация: 24-08-07
Из: БРЕСТ
Пользователь №: 30 053



Я конечно вижу (и понимаю) что подобных тем создано много, ну хотя бы несколько. Но почитав их, увидел, что они мне не подходят, точнее не дают ответы на необходимые мне вопросы. А вопросов будет походу много. Поэтому решил создать новую тему в немного другом стиле – т.е. с моими промежуточными выводами, дабы на примере эволюции чайника помочь новым юзерам.
Ось решил прикрутить к уже готовому проекту – железо(на ATmega32) + дрова периферии (написано на С). Что бы грамотно прикрутить ось нужно понять как она работает. В общем как работает ось, я в принципе представляю, по крайней мере, в общих чертах. Как то даже написал свой вытесняющий планировщик для ARM (Работает до сих пор smile.gif. Ну да ладно. Почитал доку по оси v.2 почитал форумы. В голове образовалась определённый набор знаний в виде каши, ну или первичного супа, типа из которого на планете жизнь зарождалась smile.gif Понял, что пора внедрять знания. Вставил иссодники оси в мой проект. Расставил их соответственно папковой иерархии проекта. Долго бился над путями. Потом плюнул и прикрутил исходники к проекту 1-EventFlag. Ну вроде нормально. Компилиться без ошибок.
Теперь пару тезисов которые я для себя определил, как некие точки от которых можно оттолкнуться.
1.Поток (кусок кода в while(1){}) будет выполняться пока
a) надо вызвать паузу (за это отвечает функция, как я понял, Sleep)
б)не произойдёт прерывание переферии, внутри которого произойдёт переключения контекста. Для этого мы в обработчики прерывания вставляем объект класса TISR_Wrapper. Вставляем этот объект, например, в прерывание UART recive.
в) Прерывание системного таймера. Таймер настроенный на срабатывание через определённый промежуток времени для проверки надо ли переключать контекст.
2. Шедулер или планировщик. Кусок кода который контролирует паузы для потоков – т.е. инкрементирует их если надо, смотрит какие флаги взвелись для ожидающих их потоков и т.д. ну и соответственно переключает потоки. Примерно так.

Вроде определились с необходимыми вещами. Приступаем.
Нам нужен системный таймер. На его роль определили Timer0. В общем проинитил его. Включил прерывание на переполнение. Время срабатывания решил поставить 1мс. И для этого в теле прерывания надо таймер инитить TCNT0 = 0x8D, это при кварце 7.3728. Порыл код и догадалcя что вроде для этого есть функция void OS::SystemTimerUserHook(), короче туда и вставил. Правильно сделал?
C таймером разобрались. Теперь эпопея номер два – програмное прерывание. Почитал за него. Блин, сложно въехать в сакраментальный смысл его использования, ну это и понятно надо сначала поюзать ось и столкнувшись с проблемами всё станет на свои полочки. Но как я уже говорил железо уже определено и костыль в виде соединения пинов мне не подходит. Отсюда мой первый вопрос. Как выпутаться из этой проблемы? Конечно, хотеться всё же использовать именно прерывание, т.к. использования прямого вызова шедулера очень не кашерно, как я прочитал в документации. Желательно не просто сказать – бери гэто, а привести пример кода, именно в контексте оси.
Спасибо.


--------------------
Если хочешь вбить гвоздь, не ищи обходных путей, просто бери молоток и бей по этому чёртовому гвоздю!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Beginning
сообщение Apr 28 2010, 19:50
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 511
Регистрация: 24-08-07
Из: БРЕСТ
Пользователь №: 30 053



Спасибо, не ожидал столь тёплого и развёрнутого ответа, особенно после того как модератор сделал приписку к названию темы.
Цитата(Сергкй Борщ)
Вы не учитываете, что "за время пути собака могла подрасти". Пока исполнение дойдет до точки, где вы перезаписываете счетчик, таймер может сделать несколько тиков. Поэтому надо делать TCNT0 -= 0x100-0x8D.

Не совсем понял, что вы имели ввиду, но попытаюсь ответить, так как я понял. Собака(watchdog)… а при чём здесь собака? Я обычно собаку ставлю на 2 секунды, и сбрасываю в прерывании от таймера которое делаю на 0,1с. Здесь тоже собаку буду в SystemTimerUserHook сбрасывать.Пусть таймер делает сколько угодно тиков, вроде как главное что перед выходом я ставлю TCNT0=0x8D?
В чём смысл выражения TCNT0 -= 0x100-0x8D? Компилятор его переделает же в TCNT0 -= 0x73.
Про прерывание в общем понятно.
Цитата(Сергей Борщ)
Используйте прерывание SPM. Пример есть в портах под avr-gcc.

Посмотрел все три проекта(v3.1) и везде используеться TIMER1_COMPA, или не там смотрел? Тогда где?
Кстати использую IAR.


--------------------
Если хочешь вбить гвоздь, не ищи обходных путей, просто бери молоток и бей по этому чёртовому гвоздю!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 29 2010, 06:14
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Beginning @ Apr 28 2010, 22:50) *
Не совсем понял, что вы имели ввиду, но попытаюсь ответить, так как я понял. Собака(watchdog)… а при чём здесь собака?
Простите. Это была строка из детского стихотворения Маршака. Я как-то не подумал, что кто-то в детстве мог его не слышать. Watchdog тут совершенно не при чем laughing.gif .
Цитата(Beginning @ Apr 28 2010, 22:50) *
Пусть таймер делает сколько угодно тиков, вроде как главное что перед выходом я ставлю TCNT0=0x8D?
В чём смысл выражения TCNT0 -= 0x100-0x8D?
Вам надо, чтобы между прерываниями прошло 0x73 тиков. Допустим, действуем по-вашему. Происходит прерывание, за время до перезаписи, допустим, проходит еще 2 тика. Вы записываете 0x8D. С этого момента таймер отсчитывает 0x100-0x8D = 0x73 тиков и вызывается новое прерывание. Но еще два тика было да перезаписи, итого между прерываниями прошло 0x75 тиков. Теперь заменяем TCNT0 = 0x8D на TCNT0 -= 0x100-0x8D. На момент этой строки в TCNT находится 2, выполняяя вычитание получаем в нем 8F. Итого таймеру до прерывания осталось 0x100 - 0x8F = 0x71 тик и еще два было до вычитания. Итого между прерываниями прошло 0x73 тика, как и требовалось. А если было какое-то еще прерывание, и прерывание таймера было отложено - там может натикать не 2 а гораздо больше. При вычитании эта ошибка не будет накапливаться.

Цитата(Beginning @ Apr 28 2010, 22:50) *
Компилятор его переделает же в TCNT0 -= 0x73.
Принцип IBM: "Машина должна работать, а человек - думать". Если бы я написал TCNT0 -= 0x73, то возник бы вопрос - откуда взялось это число. А так сразу видно - это столько тиков, сколько осталось до переполнения таймера, чтобы получить ваше число 0x8D. На выходной код не влияет, но делает программу более читабельной. Вообще писать в исходнике подобные "магические числа" - дурной тон. Гораздо понятнее писать примерно так:
Код
#define OS_TICK_RATE    1000 // Hz
#define SYSTIMER_FREQ      (F_CPU / 4)

...
TCNT0 -= SYSTIMER_FREQ / OS_TICK_RATE;
Компилятор посчитает, ему не трудно - это его работа. Эти же именованные константы можно использовать и в других местах исходника, и при создании на базе этого проекта другого, с другим кварцем, вам достаточно будет изменить всего одну строку и не перелопачивать весь исходник в поисках "магических чисел".

Цитата(Beginning @ Apr 28 2010, 22:50) *
Посмотрел все три проекта(v3.1) и везде используеться TIMER1_COMPA, или не там смотрел? Тогда где?
Кстати использую IAR.
Посмотрите порт под avr-gcc


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Beginning   scmRTOS для начинающего.   Apr 28 2010, 15:13
- - Сергей Борщ   Цитата(Beginning @ Apr 28 2010, 18:13) 1....   Apr 28 2010, 18:13
- - Beginning   Спасибо за разъяснение про таймер. Ход ваших мысле...   Apr 29 2010, 11:23
|- - Сергей Борщ   Цитата(Beginning @ Apr 29 2010, 14:23) Кс...   Apr 29 2010, 11:43
- - Beginning   Огромное спасибо! Буду разбираться.   Apr 29 2010, 11:50
- - Beginning   Вот заготовка протеуса, контроллер и светодиод. По...   Apr 30 2010, 06:00
|- - Сергей Борщ   Цитата(Beginning @ Apr 30 2010, 09:00) Во...   Apr 30 2010, 06:07
- - Beginning   Я не хотел вас как то задеть, даже и в мыслях не б...   Apr 30 2010, 06:16
- - Beginning   Интересный эффект – когда убираешь оптимизацию в I...   Apr 30 2010, 07:47
- - Сергей Борщ   Цитата(Beginning @ Apr 30 2010, 09:16) В ...   Apr 30 2010, 09:40
- - Beginning   ЦитатаОй, на этом форуме достаточно сообщений ...   Apr 30 2010, 09:58
- - IgorKossak   Цитата(Beginning @ Apr 30 2010, 12:58) А ...   Apr 30 2010, 12:22


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 23:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01387 секунд с 7
ELECTRONIX ©2004-2016