Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: родить аналог difftime() и time()
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
evgen2
Граждане, не подскажете, где бы взять исходники аналога функции difftime() в обычных сях ?

Есть RTC, есть регистры, из которых можно родить структуру со временем. Но как ее перевести в секунды с начала хоть 1970, хоть 1980 или любого другого года - непонятно (или, что тоже самое - родить аналог time() ). Задача состоит в определении интервала времени между событиями порядка часов-суток-месяцев. При этом не хотелось бы промахиваться мимо тазика в районе 28-29 февраля...

UPDATE: с удивлением обнаружил \Keil\ARM\RV31\INC\time.h Почему я это не нашел ночью - не знаю. В хелпе обещают, что

* mktime() and localtime() can be used immediately
* time() and clock() are system-specific and probably not usable unless reimplemented
* asctime(), ctime(), and strftime() require locale.

Dron_Gus
localtime() mktime() Вам в помощь. (time.h)
evgen2
Цитата(Dron_Gus @ Sep 17 2010, 10:48) *
localtime() mktime() Вам в помощь. (time.h)

так нету такого.

Уточняю - процессоры lpc21xx, 23xx и 17хх и никаких линуксов.
Dron_Gus
Не знаю, что за компилятором Вы пользуетесь (Вы его не указали). Но с CrossStudio (GCC) и IAR библиотеки с такими функциями идут.
_Pasha
Цитата(evgen2 @ Sep 17 2010, 11:47) *
и никаких линуксов.

если скажете еще, что никаких newlib'ов, Вам не поверят smile.gif
evgen2
Цитата(Dron_Gus @ Sep 17 2010, 12:19) *
Не знаю, что за компилятором Вы пользуетесь (Вы его не указали). Но с CrossStudio (GCC) и IAR библиотеки с такими функциями идут.

keil'ом
Dron_Gus
Похоже в MDK их действительно нет. Тогда http://www.google.com/codesearch
evgen2
Цитата(_Pasha @ Sep 17 2010, 12:20) *
если скажете еще, что никаких newlib'ов, Вам не поверят smile.gif

что такое newlib слава богу отвечает гугль.
и там, как и в других линуксах есть difftme() и time()

но всего лишь как обертки к gettimeofday(), которое внутре издаёт сисколл, который возвращает структуру time_t, в которой одно из полей - количество секунд с начала эпохи. регистры RTC содержат все поля time_t кроме tv_sec
Dron_Gus
time() возвращает количество секунд от... бла-бла-бла... его можно получить пересчетом регистров RTC функцией mktime.
difftime() это что-то вроде:
double difftime ( time_t time2, time_t time1 )
{
return (time2 - time1);
}
evgen2
Цитата(Dron_Gus @ Sep 17 2010, 12:59) *
time() возвращает количество секунд от... бла-бла-бла... его можно получить пересчетом регистров RTC функцией mktime.
difftime() это что-то вроде:
double difftime ( time_t time2, time_t time1 )
{
return (time2 - time1);
}


Да, похоже что надо было искать mktime

но находится оно какое-то некузявое для embedded

http://www.google.com/codesearch/p?hl=ru#e...mktime%20lang:c

Сколько оно будет выполнятся - хз
sasamy
Цитата(evgen2 @ Sep 17 2010, 13:13) *
но находится оно какое-то некузявое для embedded

http://www.google.com/codesearch/p?hl=ru#e...mktime%20lang:c


Мда - зубодробильня какая-то...

On a POSIX system, time_t is an arithmetic type, and one could just define
#define difftime(t1,t0) (double)(t1 - t0)

Реализацию остального можно посмотреть тут
http://prex.sourceforge.net/src/files/1129.html
VAI
Посмотрите во вложении.
Функции преобразования даты в long-переменную, показывающую кол-во секунд и функции обратного преобразования.
Украл то ли здесь, то ли на сахаре. Немного подшаманил.
evgen2
Цитата(sasamy @ Sep 17 2010, 13:37) *
Мда - зубодробильня какая-то...

On a POSIX system, time_t is an arithmetic type, and one could just define
#define difftime(t1,t0) (double)(t1 - t0)

Реализацию остального можно посмотреть тут
http://prex.sourceforge.net/src/files/1129.html


О, это явно проще, хотя засада очевидно перенесена в isleap(year)

И, как видно из mktime() - этот самый isleap будет нынче вызываться 40 раз, что явно не радует. Впрочем тут явно есть место для оптимизации.

Код
for (year = 1970; year < (unsigned int)(1900 + tmp->tm_year); year++)
               days += DAYSPERNYEAR + (isleap(year) ? 1 : 0);

Dron_Gus
А зачем каждый раз пересчитывать? У Вас в процессоре же есть прерывания с известным периодом? Тики операционки или еще что? Ну и делайте раз в секунду cur_time++; И вместо пересчета просто возвращайте текущее значение. Можно синхронизироваться периодически с внешними часами.
sasamy
Цитата(Dron_Gus @ Sep 17 2010, 14:19) *
А зачем каждый раз пересчитывать? У Вас в процессоре же есть прерывания с известным периодом? Тики операционки или еще что? Ну и делайте раз в секунду cur_time++; И вместо пересчета просто возвращайте текущее значение. Можно синхронизироваться периодически с внешними часами.


Так собственно делается и в этой ОС,

http://prex.sourceforge.net/src/S/85.html

evgen2
Цитата(Dron_Gus @ Sep 17 2010, 14:19) *
А зачем каждый раз пересчитывать? У Вас в процессоре же есть прерывания с известным периодом? Тики операционки или еще что? Ну и делайте раз в секунду cur_time++; И вместо пересчета просто возвращайте текущее значение. Можно синхронизироваться периодически с внешними часами.

есть RTC - real time clock, которая запитывается от батарейки. В промежутках между событиями процессор может быть выключен. Сами события, т.е. времена записываются или во флеш или в Battery RAM.
Сам промежуток может быть большим, так что к прерываниям привязываться стремно, даже если питание не выключается.

В принципе решение лежало на поверхности, но, почему-то я умудрился его не найти ;-)

В Keile есть "time.h" из которого можно использовать mktime, предварительно заполнив поля struct tm

Код
void RTC_GetTime(struct tm *t)
{
   t->tm_sec  = RTC_SEC;   /* seconds after the minute, 0 to 60
                     (0 - 60 allows for the occasional leap second) */
   t->tm_min  = RTC_MIN;   /* minutes after the hour, 0 to 59 */
   t->tm_hour = RTC_HOUR;  /* hours since midnight, 0 to 23 */
   t->tm_mday = RTC_DOM;  /* day of the month, 1 to 31 */
   t->tm_mon  = RTC_MONTH;   /* months since January, 0 to 11 */
   t->tm_year = RTC_YEAR-1900;  /* years since 1900 */
   t->tm_wday = RTC_DOW;  /* days since Sunday, 0 to 6 */
   t->tm_yday = RTC_DOY;  /* days since January 1, 0 to 365 */
   t->tm_isdst = 0; /* Daylight Savings Time flag */

}


mktime() вопреки ожиданиям не тормозит, а вот стандартной time() пользоваться нельзя, оно возвращает -1.
Dron_Gus
Цитата(evgen2 @ Sep 17 2010, 15:33) *
mktime() вопреки ожиданиям не тормозит, а вот стандартной time() пользоваться нельзя, оно возвращает -1.

time() как раз надо написать самому. smile.gif
evgen2
Цитата(Dron_Gus @ Sep 17 2010, 15:39) *
time() как раз надо написать самому. smile.gif


ну так берем функцию выше и добавляем mktime
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.