Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Техника точных засечек времени в малоразрядных системах.
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Программирование
Evgeny_CD
Одна их самых противных проблем малоразрядных (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 Можно написать код, который даст нам одинаковое время "определения засечки" при любом варианте, что устранит ненужный джиттер.

Критика идеи, делал ли так кто-нибудь?
XVR
Есть метод проще:

Читаем U32, U16 и снова U32. Если первое и последнее значение, прочтенное из U32 не совпали - все чтения повторяются (было переполнение таймера и прерывание).
rezident
Я не встречался с приложениями где требовались бы отсчеты времени точнее 1мс. Поэтому в своих приложениях использую беззнаковый счетчик "тиков", который инкрементируется в прерывании на величину кратную миллисекундам. Не обязательно на 1мс. Квант может и 5мс быть и 16мс, в зависимости от периода прерывания. Но переменная тиков имеет такую размерность, которая заведомо обеспечивает атомарность обращения к ней. Абсолютная разница между двумя обращениями к переменной "тиков" дает интервал времени, пропорционально которому увеличивается искомая переменная секунд или миллисекунд U32, к которой уже можно обратиться через функцию. Почему через функцию, а не напрямую? Потому, что внутри одной функции обеспечить атомарность обращения к переменной проще, чем где-нипопадя. К тому же масштабирование "тиков" в секунды или миллисекунды происходит именно в ней.
Ах, да, забыл уточнить, что период вызовов функции инкремента секунд (или миллисекунд) переменной U32 конечно же меньше, чем период переполнения счетчика "тиков".
Дон Амброзио
Цитата(rezident @ Jun 17 2008, 13:11) *
Я не встречался с приложениями где требовались бы отсчеты времени точнее 1мс. Поэтому ...

А я встречался и постоянно встречаюсь с приложениями, где требуется точность временной привязки 1 такт процессора......... И я её успешно обеспечиваю... Так что....
rezident
Цитата(Дон Амброзио @ Jun 23 2008, 02:39) *
А я встречался и постоянно встречаюсь с приложениями, где требуется точность временной привязки 1 такт процессора......... И я её успешно обеспечиваю... Так что....
По теме есть что сказать? Если нет, то не флудите, господин Туес... эээ... ТумамОзес.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.