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

 
 
 
Reply to this topicStart new topic
> Техника точных засечек времени в малоразрядных системах., Вроде сложилось.
Evgeny_CD
сообщение Jun 13 2008, 21:56
Сообщение #1


Гуру
******

Группа: СуперМодераторы
Сообщений: 2 065
Регистрация: 11-01-05
Из: Москва
Пользователь №: 1 892



Одна их самых противных проблем малоразрядных (8 и 16) систем - атоммарность при работе с большими структурами данных.

Пусть у нас есть 16 битный таймер, у которого есть регистр match. По совпадению происходит прерывание.

Точное время состоит из U16, прочитанного из таймера, и U32, прочитанного из системной области памяти. При тактовой 8 Мгц переполнение такого счетчика наступит более, чем через год
((2^48)*(1/(8*(10^6))))/(3600*24) = более 407 дней

Если такой таймер "питать" от 32768 гц, то будет ваще здорово smile.gif
((2^48)*(1/32768))/(3600*24*365)=272 года. "Вы здохните раньше, чем Ваше устройство." 30 мкс разрешение - не так уж и плохо для многих практических применений.

В варианте 16 битной системной переменной имеем
((2^32)*(1/32768))/(3600*24) = 1.5 дня, что тоже достаточно для многих практических задач.

Когда мы читаем U16, у нас есть опасность, что прерывание уже взведено, но не отработало, и системную переменную никто не увеличил. Если пытаться проверить контроллер прерываний, то он, чего доброго, еще сбросит какой-нибудь флаг, это долго и нудно.

Мы пойдем другим путем.

Кроме U32, есть еще некая системная переменная U16, которая описывает, когда таймер достигнет порога прерывания. При обработке прерывания вначале инкрементируется U32, затем U16 timer_limit перед самым выходом из прерывания.

В юзеровском потоке читаем эту переменную timer_limit, и читаем таймер. Если таймер меньше (с учетом кольцевого счета!) переменной, прерывание не достигнуто, можно читать U32 из системной области.

Если таймер >= timer_limit, то системная переменная пока не валидна, и надо подождать, пока не изменится timer_limit. Как только она изменилась - все, прерывание отработало, можно "идти" за системной переменной U32.

В отличие от приходивших мне в голову ранее идей, такой подход не требует какой-либо записи в счетные регистры таймера, что гарантирует высокую равномерность его работы.

Ну а для нас появляется инструмент точного хронометража прохождения участков кода.

Кстати, приведенный выше подход можно слегка усовершенствовать.

Compare всгда ставится на "старший бит таймера". Т.е. для 16 битного таймера 0x8000. Служебная системная переменная показывает, какой "половинке" таймера соотвествует U32 в памяти. Если мы не перешли половинку, то U32 валидна. Если перешли, и это обнаруживается по разнице служебной переменной и таймера, то можно самостоятельно проинкрементировать U32 smile.gif Можно написать код, который даст нам одинаковое время "определения засечки" при любом варианте, что устранит ненужный джиттер.

Критика идеи, делал ли так кто-нибудь?
Go to the top of the page
 
+Quote Post
XVR
сообщение Jun 17 2008, 08:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Есть метод проще:

Читаем U32, U16 и снова U32. Если первое и последнее значение, прочтенное из U32 не совпали - все чтения повторяются (было переполнение таймера и прерывание).
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 17 2008, 09:11
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Я не встречался с приложениями где требовались бы отсчеты времени точнее 1мс. Поэтому в своих приложениях использую беззнаковый счетчик "тиков", который инкрементируется в прерывании на величину кратную миллисекундам. Не обязательно на 1мс. Квант может и 5мс быть и 16мс, в зависимости от периода прерывания. Но переменная тиков имеет такую размерность, которая заведомо обеспечивает атомарность обращения к ней. Абсолютная разница между двумя обращениями к переменной "тиков" дает интервал времени, пропорционально которому увеличивается искомая переменная секунд или миллисекунд U32, к которой уже можно обратиться через функцию. Почему через функцию, а не напрямую? Потому, что внутри одной функции обеспечить атомарность обращения к переменной проще, чем где-нипопадя. К тому же масштабирование "тиков" в секунды или миллисекунды происходит именно в ней.
Ах, да, забыл уточнить, что период вызовов функции инкремента секунд (или миллисекунд) переменной U32 конечно же меньше, чем период переполнения счетчика "тиков".
Go to the top of the page
 
+Quote Post
Дон Амброзио
сообщение Jun 22 2008, 20:39
Сообщение #4


Местный
***

Группа: Участник*
Сообщений: 323
Регистрация: 11-02-08
Пользователь №: 34 947



Цитата(rezident @ Jun 17 2008, 13:11) *
Я не встречался с приложениями где требовались бы отсчеты времени точнее 1мс. Поэтому ...

А я встречался и постоянно встречаюсь с приложениями, где требуется точность временной привязки 1 такт процессора......... И я её успешно обеспечиваю... Так что....

Сообщение отредактировал Дон Амброзио - Jun 22 2008, 20:43


--------------------
После устранения бага в программе она стала работать....хуже
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 22 2008, 20:47
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Дон Амброзио @ Jun 23 2008, 02:39) *
А я встречался и постоянно встречаюсь с приложениями, где требуется точность временной привязки 1 такт процессора......... И я её успешно обеспечиваю... Так что....
По теме есть что сказать? Если нет, то не флудите, господин Туес... эээ... ТумамОзес.
Go to the top of the page
 
+Quote Post

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

 


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


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