|
Программный таймер, как красиво обойти переполнение? |
|
|
|
Jan 24 2014, 09:53
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Есть прерывание с периодом 1 мс, где инкрементируется 32-разрядный счетчик: Код void SysTick_Handler(void) { TSysTimer::Counter++; } При необходимости формирования интервала программа может запустить один из программных счетчиков: Код void TSoftTimer::Start(uint32_t t) { FinalCount = TSysTimer::Counter + t; } Истек ли интервал, проверяется так: Код bool TSoftTimer::Over(void) { return(TSysTimer::Counter >= FinalCount); } Всё хорошо, но примерно через 50 дней счетчик TSysTimer::Counter переполнится и всё сломается. Как красиво это обойти? При этом можно наложить ограничение, что формируемый интервал никогда не превышает половины (или даже четверти) периода счетчика, а проверка переполнения тоже делается часто, много раз за период счетчика.
--------------------
|
|
|
|
|
 |
Ответов
|
Apr 1 2015, 08:55
|

Частый гость
 
Группа: Свой
Сообщений: 167
Регистрация: 25-12-09
Из: Минск
Пользователь №: 54 460

|
Цитата(scifi @ Jan 24 2014, 13:49)  +1. Кстати, стандарт Си гарантирует, что при вычитании (unsigned int) - (unsigned int) результат будет корректным, пока разница во времени не превышает те самые 50 дней (для 32 бит), несмотря на переполнение первой или второй переменной. У меня тут тоже с коллегами разгорелся спор, можно ссылку на стандарт с упоминанием этой гарантии, не могу найти.
|
|
|
|
|
Apr 1 2015, 10:16
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(Integro @ Apr 1 2015, 15:55)  У меня тут тоже с коллегами разгорелся спор, можно ссылку на стандарт с упоминанием этой гарантии, не могу найти. В стандарте С (6.2.5.9) есть такой текст: Цитата The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the representation of the same value in each type is the same.33)A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type. А стандарт С++ в (3.9.1) содержит такой текст: Цитата Unsigned integers shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer. и ниже примечание, совпадающее по смыслу с текстом из стандарта С, про арифметику по модулю 2 n. Впрочем всё это фигня и словесная эквилибристика. А правда жизни состоит в том, что все эти свойства и поведение знаковых и беззнаковых типов диктуются устройством АЛУ и принятым в подавляющем большинстве современных машин представлением знаковых целых в так называемом "двоичном коде с дополнением до 2". Преимущество такого представления - то что АЛУ работает совершенно одинаково, а разница signed/unsigned учитывается только при интерпретации признаков переполнения и переноса ( C и V ), и при многоразрядной арифметике, для правильно учёта переноса из младшего слова в старшее. Изначально С неявно предполагал именно такое представление целых (как и сделано в PDP-11, на которых он изначально появился). Альтернативные представления уже тогда были редкостью. Все более поздние изменения стандартов в части целочисленной арифметики и сдвигов просто витиевато выражают простую мысль: "делайте что хотите, но результат должен быть такой же как на "нормальных" процессорах использующих код с дополнением до двойки". То есть сначала было придумано АЛУ, работающее с неотрицательными целыми числами, потом придумано как представлять отрицательные числа так, чтобы не переделывать АЛУ, а уж потом сочинители стандартов попытались описать что получилось так как они умеют это делать.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
Сообщений в этой теме
Леонид Иванович Программный таймер Jan 24 2014, 09:53    Integro Цитата(SSerge @ Apr 1 2015, 13:16)
Спаси... Apr 1 2015, 11:50 demiurg_spb Цитата(ViKo @ Jan 24 2014, 14:21) +1 Всег... Jan 24 2014, 11:16 Tarbal Цитата(ViKo @ Jan 24 2014, 13:21) Нужно н... Jan 24 2014, 12:59  ViKo Цитата(Tarbal @ Jan 24 2014, 15:59) Важно... Jan 24 2014, 14:03   scifi Цитата(ViKo @ Jan 24 2014, 18:03) Возможн... Jan 24 2014, 14:28 RabidRabbit не знаю, как на ARM, а для x64 вычитание не прокат... Jan 24 2014, 11:21 scifi Цитата(RabidRabbit @ Jan 24 2014, 15:21) ... Jan 24 2014, 12:17  Леонид Иванович О, спасибо, точно! А я было зациклился на срав... Jan 24 2014, 12:24  RabidRabbit Цитата(scifi @ Jan 24 2014, 16:17) Вы нев... Jan 25 2014, 07:20   scifi Цитата(RabidRabbit @ Jan 25 2014, 11:20) ... Jan 25 2014, 07:58 Genadi Zawidowski а в NT x86 таймер 64 бита... и процедура получения... Jan 24 2014, 13:21 mantech Цитата(Genadi Zawidowski @ Jan 24 2014, 17... Jan 24 2014, 17:50  Golikov A. Цитата(mantech @ Jan 24 2014, 21:50) Дак ... Jan 24 2014, 18:48   Genadi Zawidowski Цитата(Golikov A. @ Jan 24 2014, 22:48) д... Jan 24 2014, 21:28 Golikov A. А я вечно горожу проверку что типа если текущее ме... Jan 24 2014, 13:49 Golikov A. для без знакового все просто, пусть 8 бит
250 - с... Jan 24 2014, 16:50 Golikov A. если 100 нан, то переполнение через 58.5 тыс лет.
... Jan 25 2014, 05:48 Ruslan-maniak НО в данном способе (с вычитанием) мы должны гаран... Oct 28 2014, 08:30 Сергей Борщ Цитата(Ruslan-maniak @ Oct 28 2014, 10... Oct 28 2014, 08:54 Ruslan-maniak В этом и заключается мой вопрос. В приведённом при... Oct 28 2014, 09:50 ViKo Цитата(Ruslan-maniak @ Oct 28 2014, 12... Oct 28 2014, 10:27 Ruslan-maniak На практике получается что если от меньшего беззна... Oct 28 2014, 10:46 Golikov A. вы про какой из примеров то?
return(TSysTimer::Co... Oct 28 2014, 10:52 Ruslan-maniak Вот взяли мы это 7, и хотим что бы таймер сработал... Oct 28 2014, 11:01 ViKo Не так (я неправильно написал выше). Вам нужен инт... Oct 28 2014, 11:06 Ruslan-maniak Но таким образом на каждый случай приходится по 2 ... Oct 28 2014, 11:14 ViKo Тогда потеряете половину диапазона. Oct 28 2014, 11:24 Ruslan-maniak Да я как-то не рассчитываю использовать интервал б... Oct 28 2014, 11:30 scifi Цитата(Ruslan-maniak @ Oct 28 2014, 14... Oct 28 2014, 11:38 Golikov A. да тут не вопрос диапазона, а вопрос постановки за... Oct 28 2014, 12:07 ViKo Вычисляя разность между текущим значением таймера ... Oct 28 2014, 12:16 Ruslan-maniak Да, цель именно выжать максимальную оптимизацию ка... Oct 28 2014, 16:52 jcxz Пипец! Не ожидал такого мусоленья здесь соверш... Oct 28 2014, 18:10 scifi Цитата(Ruslan-maniak @ Oct 28 2014, 19... Oct 28 2014, 20:13 Ruslan-maniak jcxz, вы предложили то же самое: использовать 2 пе... Oct 29 2014, 03:38 jcxz Цитата(Ruslan-maniak @ Oct 29 2014, 09... Oct 29 2014, 04:54 Ruslan-maniak Считайте по пальцам из вашего примера: переменная ... Oct 29 2014, 05:31 jcxz Цитата(Ruslan-maniak @ Oct 29 2014, 11... Oct 29 2014, 08:13 Golikov A. Давайте поглядим
Плюсы минусы вашей оптимизации
М... Oct 29 2014, 05:34 Ruslan-maniak 1. Вы реально использовали миллисекундный таймер д... Oct 29 2014, 05:44 Golikov A. 1. Почему нет, я участвовал в разработке системы к... Oct 29 2014, 08:53 SSerge Почитал ради интереса библиотеки stm32cubef4.
Там ... Apr 1 2015, 14:13 Golikov A. ЦитатаУ меня тут тоже с коллегами разгорелся спор,... Apr 1 2015, 15:51 scifi Цитата(Golikov A. @ Apr 1 2015, 18:51) на... Apr 1 2015, 19:28 Golikov A. Причем тут это?
Покажите мне место в стандарте где... Apr 1 2015, 19:44 scifi Цитата(Golikov A. @ Apr 1 2015, 22:44) ес... Apr 1 2015, 21:26 Integro Да, я полностью с вами согласен, но аргумент ... Apr 1 2015, 20:25 Golikov A. Вам нравиться слово реверс инжиниринг?
Данный воп... Apr 2 2015, 06:40
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|