ctime.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-08-21 zhangjun copy from minilibc
  9. * 2020-09-07 Meco Man combine gcc armcc iccarm
  10. * 2021-02-05 Meco Man add timegm()
  11. * 2021-02-07 Meco Man fixed gettimeofday()
  12. * 2021-02-08 Meco Man add settimeofday() stime()
  13. * 2021-02-10 Meco Man add ctime_r() and re-implement ctime()
  14. * 2021-02-11 Meco Man fix bug #3183 - align days[] and months[] to 4 bytes
  15. * 2021-02-12 Meco Man add errno
  16. * 2012-12-08 Bernard <clock_time.c> fix the issue of _timevalue.tv_usec initialization,
  17. * which found by Rob <rdent@iinet.net.au>
  18. * 2021-02-12 Meco Man move all of the functions located in <clock_time.c> to this file
  19. * 2021-03-15 Meco Man fixed a bug of leaking memory in asctime()
  20. * 2021-05-01 Meco Man support fixed timezone
  21. * 2021-07-21 Meco Man implement that change/set timezone APIs
  22. */
  23. #include "sys/time.h"
  24. #include <sys/errno.h>
  25. #include <rtthread.h>
  26. #include <rthw.h>
  27. #include <unistd.h>
  28. #ifdef RT_USING_SMART
  29. #include "lwp.h"
  30. #endif
  31. #ifdef RT_USING_POSIX_DELAY
  32. #include <delay.h>
  33. #endif
  34. #if defined( RT_USING_RTC ) || defined( RT_USING_CPUTIME)
  35. #include <rtdevice.h>
  36. #endif
  37. #define DBG_TAG "time"
  38. #define DBG_LVL DBG_INFO
  39. #include <rtdbg.h>
  40. #define _WARNING_NO_RTC "Cannot find a RTC device!"
  41. /* seconds per day */
  42. #define SPD 24*60*60
  43. /* days per month -- nonleap! */
  44. static const short __spm[13] =
  45. {
  46. 0,
  47. (31),
  48. (31 + 28),
  49. (31 + 28 + 31),
  50. (31 + 28 + 31 + 30),
  51. (31 + 28 + 31 + 30 + 31),
  52. (31 + 28 + 31 + 30 + 31 + 30),
  53. (31 + 28 + 31 + 30 + 31 + 30 + 31),
  54. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
  55. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
  56. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
  57. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
  58. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31),
  59. };
  60. rt_align(4) static const char *days = "Sun Mon Tue Wed Thu Fri Sat ";
  61. rt_align(4) static const char *months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
  62. #ifndef __isleap
  63. static int __isleap(int year)
  64. {
  65. /* every fourth year is a leap year except for century years that are
  66. * not divisible by 400. */
  67. /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
  68. return (!(year % 4) && ((year % 100) || !(year % 400)));
  69. }
  70. #endif
  71. static void num2str(char *c, int i)
  72. {
  73. c[0] = i / 10 + '0';
  74. c[1] = i % 10 + '0';
  75. }
  76. /**
  77. * Get time from RTC device (without timezone, UTC+0)
  78. * @param tv: struct timeval
  79. * @return the operation status, RT_EOK on successful
  80. */
  81. static rt_err_t get_timeval(struct timeval *tv)
  82. {
  83. #ifdef RT_USING_RTC
  84. static rt_device_t device = RT_NULL;
  85. rt_err_t rst = -RT_ERROR;
  86. if (tv == RT_NULL)
  87. return -RT_EINVAL;
  88. /* default is 0 */
  89. tv->tv_sec = 0;
  90. tv->tv_usec = 0;
  91. /* optimization: find rtc device only first */
  92. if (device == RT_NULL)
  93. {
  94. device = rt_device_find("rtc");
  95. }
  96. /* read timestamp from RTC device */
  97. if (device != RT_NULL)
  98. {
  99. if (rt_device_open(device, 0) == RT_EOK)
  100. {
  101. rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &tv->tv_sec);
  102. rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIMEVAL, tv);
  103. rt_device_close(device);
  104. }
  105. }
  106. else
  107. {
  108. LOG_W(_WARNING_NO_RTC);
  109. return -RT_ENOSYS;
  110. }
  111. return rst;
  112. #else
  113. LOG_W(_WARNING_NO_RTC);
  114. return -RT_ENOSYS;
  115. #endif /* RT_USING_RTC */
  116. }
  117. /**
  118. * Set time to RTC device (without timezone)
  119. * @param tv: struct timeval
  120. * @return the operation status, RT_EOK on successful
  121. */
  122. static int set_timeval(struct timeval *tv)
  123. {
  124. #ifdef RT_USING_RTC
  125. static rt_device_t device = RT_NULL;
  126. rt_err_t rst = -RT_ERROR;
  127. if (tv == RT_NULL)
  128. return -RT_EINVAL;
  129. /* optimization: find rtc device only first */
  130. if (device == RT_NULL)
  131. {
  132. device = rt_device_find("rtc");
  133. }
  134. /* read timestamp from RTC device */
  135. if (device != RT_NULL)
  136. {
  137. if (rt_device_open(device, 0) == RT_EOK)
  138. {
  139. rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &tv->tv_sec);
  140. rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIMEVAL, tv);
  141. rt_device_close(device);
  142. }
  143. }
  144. else
  145. {
  146. LOG_W(_WARNING_NO_RTC);
  147. return -RT_ENOSYS;
  148. }
  149. return rst;
  150. #else
  151. LOG_W(_WARNING_NO_RTC);
  152. return -RT_ENOSYS;
  153. #endif /* RT_USING_RTC */
  154. }
  155. struct tm *gmtime_r(const time_t *timep, struct tm *r)
  156. {
  157. int i;
  158. int work = *timep % (SPD);
  159. if(timep == RT_NULL || r == RT_NULL)
  160. {
  161. rt_set_errno(EFAULT);
  162. return RT_NULL;
  163. }
  164. rt_memset(r, RT_NULL, sizeof(struct tm));
  165. r->tm_sec = work % 60;
  166. work /= 60;
  167. r->tm_min = work % 60;
  168. r->tm_hour = work / 60;
  169. work = (int)(*timep / (SPD));
  170. r->tm_wday = (4 + work) % 7;
  171. for (i = 1970;; ++i)
  172. {
  173. int k = __isleap(i) ? 366 : 365;
  174. if (work >= k)
  175. work -= k;
  176. else
  177. break;
  178. }
  179. r->tm_year = i - 1900;
  180. r->tm_yday = work;
  181. r->tm_mday = 1;
  182. if (__isleap(i) && (work > 58))
  183. {
  184. if (work == 59)
  185. r->tm_mday = 2; /* 29.2. */
  186. work -= 1;
  187. }
  188. for (i = 11; i && (__spm[i] > work); --i);
  189. r->tm_mon = i;
  190. r->tm_mday += work - __spm[i];
  191. r->tm_isdst = tz_is_dst();
  192. return r;
  193. }
  194. RTM_EXPORT(gmtime_r);
  195. struct tm* gmtime(const time_t* t)
  196. {
  197. static struct tm tmp;
  198. return gmtime_r(t, &tmp);
  199. }
  200. RTM_EXPORT(gmtime);
  201. struct tm* localtime_r(const time_t* t, struct tm* r)
  202. {
  203. time_t local_tz;
  204. local_tz = *t + (time_t)tz_get() * 3600;
  205. return gmtime_r(&local_tz, r);
  206. }
  207. RTM_EXPORT(localtime_r);
  208. struct tm* localtime(const time_t* t)
  209. {
  210. static struct tm tmp;
  211. return localtime_r(t, &tmp);
  212. }
  213. RTM_EXPORT(localtime);
  214. time_t mktime(struct tm * const t)
  215. {
  216. time_t timestamp;
  217. timestamp = timegm(t);
  218. timestamp = timestamp - 3600 * (time_t)tz_get();
  219. return timestamp;
  220. }
  221. RTM_EXPORT(mktime);
  222. char* asctime_r(const struct tm *t, char *buf)
  223. {
  224. if(t == RT_NULL || buf == RT_NULL)
  225. {
  226. rt_set_errno(EFAULT);
  227. return RT_NULL;
  228. }
  229. rt_memset(buf, RT_NULL, 26);
  230. /* Checking input validity */
  231. if ((int)rt_strlen(days) <= (t->tm_wday << 2) || (int)rt_strlen(months) <= (t->tm_mon << 2))
  232. {
  233. LOG_W("asctime_r: the input parameters exceeded the limit, please check it.");
  234. *(int*) buf = *(int*) days;
  235. *(int*) (buf + 4) = *(int*) months;
  236. num2str(buf + 8, t->tm_mday);
  237. if (buf[8] == '0')
  238. buf[8] = ' ';
  239. buf[10] = ' ';
  240. num2str(buf + 11, t->tm_hour);
  241. buf[13] = ':';
  242. num2str(buf + 14, t->tm_min);
  243. buf[16] = ':';
  244. num2str(buf + 17, t->tm_sec);
  245. buf[19] = ' ';
  246. num2str(buf + 20, 2000 / 100);
  247. num2str(buf + 22, 2000 % 100);
  248. buf[24] = '\n';
  249. buf[25] = '\0';
  250. return buf;
  251. }
  252. /* "Wed Jun 30 21:49:08 1993\n" */
  253. *(int*) buf = *(int*) (days + (t->tm_wday << 2));
  254. *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2));
  255. num2str(buf + 8, t->tm_mday);
  256. if (buf[8] == '0')
  257. buf[8] = ' ';
  258. buf[10] = ' ';
  259. num2str(buf + 11, t->tm_hour);
  260. buf[13] = ':';
  261. num2str(buf + 14, t->tm_min);
  262. buf[16] = ':';
  263. num2str(buf + 17, t->tm_sec);
  264. buf[19] = ' ';
  265. num2str(buf + 20, (t->tm_year + 1900) / 100);
  266. num2str(buf + 22, (t->tm_year + 1900) % 100);
  267. buf[24] = '\n';
  268. buf[25] = '\0';
  269. return buf;
  270. }
  271. RTM_EXPORT(asctime_r);
  272. char* asctime(const struct tm *timeptr)
  273. {
  274. static char buf[26];
  275. return asctime_r(timeptr, buf);
  276. }
  277. RTM_EXPORT(asctime);
  278. char *ctime_r(const time_t * tim_p, char * result)
  279. {
  280. struct tm tm;
  281. return asctime_r(localtime_r(tim_p, &tm), result);
  282. }
  283. RTM_EXPORT(ctime_r);
  284. char* ctime(const time_t *tim_p)
  285. {
  286. return asctime(localtime(tim_p));
  287. }
  288. RTM_EXPORT(ctime);
  289. #ifndef __ICCARM__
  290. double difftime(time_t time1, time_t time2)
  291. {
  292. return (double)(time1 - time2);
  293. }
  294. #endif /* __ICCARM__ */
  295. RTM_EXPORT(difftime);
  296. RTM_EXPORT(strftime); /* inherent in the toolchain */
  297. /**
  298. * Returns the current time.
  299. *
  300. * @param time_t * t the timestamp pointer, if not used, keep NULL.
  301. *
  302. * @return The value ((time_t)-1) is returned if the calendar time is not available.
  303. * If timer is not a NULL pointer, the return value is also stored in timer.
  304. *
  305. */
  306. rt_weak time_t time(time_t *t)
  307. {
  308. struct timeval now;
  309. if(get_timeval(&now) == RT_EOK)
  310. {
  311. if (t)
  312. {
  313. *t = now.tv_sec;
  314. }
  315. return now.tv_sec;
  316. }
  317. else
  318. {
  319. rt_set_errno(EFAULT);
  320. return ((time_t)-1);
  321. }
  322. }
  323. RTM_EXPORT(time);
  324. rt_weak clock_t clock(void)
  325. {
  326. return rt_tick_get();
  327. }
  328. RTM_EXPORT(clock);
  329. int stime(const time_t *t)
  330. {
  331. struct timeval tv;
  332. if (t == RT_NULL)
  333. {
  334. rt_set_errno(EFAULT);
  335. return -1;
  336. }
  337. tv.tv_sec = *t;
  338. tv.tv_usec = 0;
  339. if (set_timeval(&tv) == RT_EOK)
  340. {
  341. return 0;
  342. }
  343. else
  344. {
  345. rt_set_errno(EFAULT);
  346. return -1;
  347. }
  348. }
  349. RTM_EXPORT(stime);
  350. time_t timegm(struct tm * const t)
  351. {
  352. time_t day;
  353. time_t i;
  354. time_t years;
  355. if(t == RT_NULL)
  356. {
  357. rt_set_errno(EFAULT);
  358. return (time_t)-1;
  359. }
  360. years = (time_t)t->tm_year - 70;
  361. if (t->tm_sec > 60) /* seconds after the minute - [0, 60] including leap second */
  362. {
  363. t->tm_min += t->tm_sec / 60;
  364. t->tm_sec %= 60;
  365. }
  366. if (t->tm_min >= 60) /* minutes after the hour - [0, 59] */
  367. {
  368. t->tm_hour += t->tm_min / 60;
  369. t->tm_min %= 60;
  370. }
  371. if (t->tm_hour >= 24) /* hours since midnight - [0, 23] */
  372. {
  373. t->tm_mday += t->tm_hour / 24;
  374. t->tm_hour %= 24;
  375. }
  376. if (t->tm_mon >= 12) /* months since January - [0, 11] */
  377. {
  378. t->tm_year += t->tm_mon / 12;
  379. t->tm_mon %= 12;
  380. }
  381. while (t->tm_mday > __spm[1 + t->tm_mon])
  382. {
  383. if (t->tm_mon == 1 && __isleap(t->tm_year + 1900))
  384. {
  385. --t->tm_mday;
  386. }
  387. t->tm_mday -= __spm[t->tm_mon];
  388. ++t->tm_mon;
  389. if (t->tm_mon > 11)
  390. {
  391. t->tm_mon = 0;
  392. ++t->tm_year;
  393. }
  394. }
  395. if (t->tm_year < 70)
  396. {
  397. rt_set_errno(EINVAL);
  398. return (time_t) -1;
  399. }
  400. /* Days since 1970 is 365 * number of years + number of leap years since 1970 */
  401. day = years * 365 + (years + 1) / 4;
  402. /* After 2100 we have to substract 3 leap years for every 400 years
  403. This is not intuitive. Most mktime implementations do not support
  404. dates after 2059, anyway, so we might leave this out for it's
  405. bloat. */
  406. if (years >= 131)
  407. {
  408. years -= 131;
  409. years /= 100;
  410. day -= (years >> 2) * 3 + 1;
  411. if ((years &= 3) == 3)
  412. years--;
  413. day -= years;
  414. }
  415. day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 +
  416. (__isleap(t->tm_year + 1900) & (t->tm_mon > 1));
  417. /* day is now the number of days since 'Jan 1 1970' */
  418. i = 7;
  419. t->tm_wday = (int)((day + 4) % i); /* Sunday=0, Monday=1, ..., Saturday=6 */
  420. i = 24;
  421. day *= i;
  422. i = 60;
  423. return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec;
  424. }
  425. RTM_EXPORT(timegm);
  426. int gettimeofday(struct timeval *tv, struct timezone *tz)
  427. {
  428. /* The use of the timezone structure is obsolete;
  429. * the tz argument should normally be specified as NULL.
  430. * The tz_dsttime field has never been used under Linux.
  431. * Thus, the following is purely of historic interest.
  432. */
  433. if(tz != RT_NULL)
  434. {
  435. tz->tz_dsttime = DST_NONE;
  436. tz->tz_minuteswest = -(tz_get() * 60);
  437. }
  438. if (tv != RT_NULL && get_timeval(tv) == RT_EOK)
  439. {
  440. return 0;
  441. }
  442. else
  443. {
  444. rt_set_errno(EINVAL);
  445. return -1;
  446. }
  447. }
  448. RTM_EXPORT(gettimeofday);
  449. int settimeofday(const struct timeval *tv, const struct timezone *tz)
  450. {
  451. /* The use of the timezone structure is obsolete;
  452. * the tz argument should normally be specified as NULL.
  453. * The tz_dsttime field has never been used under Linux.
  454. * Thus, the following is purely of historic interest.
  455. */
  456. if (tv != RT_NULL
  457. && tv->tv_usec >= 0
  458. && set_timeval((struct timeval *)tv) == RT_EOK)
  459. {
  460. return 0;
  461. }
  462. else
  463. {
  464. rt_set_errno(EINVAL);
  465. return -1;
  466. }
  467. }
  468. RTM_EXPORT(settimeofday);
  469. #ifdef RT_USING_POSIX_DELAY
  470. int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
  471. {
  472. if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND)
  473. {
  474. rt_set_errno(EINVAL);
  475. return -1;
  476. }
  477. #ifdef RT_USING_CPUTIME
  478. rt_uint64_t unit = clock_cpu_getres();
  479. rt_uint64_t ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
  480. rt_uint64_t tick = (ns * (1000UL * 1000)) / unit;
  481. rt_cputime_sleep(tick);
  482. if (rt_get_errno() == -RT_EINTR)
  483. {
  484. if (rmtp)
  485. {
  486. uint64_t rmtp_cpu_tick = tick - clock_cpu_gettime();
  487. rmtp->tv_sec = ((time_t)((rmtp_cpu_tick * unit) / (1000UL * 1000))) / NANOSECOND_PER_SECOND;
  488. rmtp->tv_nsec = ((long)((rmtp_cpu_tick * unit) / (1000UL * 1000))) % NANOSECOND_PER_SECOND;
  489. }
  490. rt_set_errno(EINTR);
  491. return -1;
  492. }
  493. #else
  494. rt_tick_t tick, tick_old = rt_tick_get();
  495. tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
  496. rt_thread_delay(tick);
  497. if (rt_get_errno() == -RT_EINTR)
  498. {
  499. if (rmtp)
  500. {
  501. tick = tick_old + tick - rt_tick_get();
  502. /* get the passed time */
  503. rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
  504. rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
  505. }
  506. rt_set_errno(EINTR);
  507. return -1;
  508. }
  509. #endif
  510. return 0;
  511. }
  512. RTM_EXPORT(nanosleep);
  513. #endif /* RT_USING_POSIX_DELAY */
  514. #ifdef RT_USING_POSIX_CLOCK
  515. #ifdef RT_USING_RTC
  516. static volatile struct timeval _timevalue;
  517. static int _rt_clock_time_system_init(void)
  518. {
  519. rt_base_t level;
  520. time_t time = 0;
  521. rt_tick_t tick;
  522. rt_device_t device;
  523. device = rt_device_find("rtc");
  524. if (device != RT_NULL)
  525. {
  526. /* get realtime seconds */
  527. if(rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time) == RT_EOK)
  528. {
  529. level = rt_hw_interrupt_disable();
  530. tick = rt_tick_get(); /* get tick */
  531. _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
  532. _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
  533. rt_hw_interrupt_enable(level);
  534. return 0;
  535. }
  536. }
  537. level = rt_hw_interrupt_disable();
  538. _timevalue.tv_usec = 0;
  539. _timevalue.tv_sec = 0;
  540. rt_hw_interrupt_enable(level);
  541. return -1;
  542. }
  543. INIT_COMPONENT_EXPORT(_rt_clock_time_system_init);
  544. #endif /* RT_USING_RTC */
  545. int clock_getres(clockid_t clockid, struct timespec *res)
  546. {
  547. #ifndef RT_USING_RTC
  548. LOG_W(_WARNING_NO_RTC);
  549. return -1;
  550. #else
  551. int ret = 0;
  552. if (res == RT_NULL)
  553. {
  554. rt_set_errno(EFAULT);
  555. return -1;
  556. }
  557. switch (clockid)
  558. {
  559. case CLOCK_REALTIME:
  560. #ifndef RT_USING_CPUTIME
  561. res->tv_sec = 0;
  562. res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND;
  563. break;
  564. #endif
  565. #ifdef RT_USING_CPUTIME
  566. case CLOCK_CPUTIME_ID:
  567. res->tv_sec = 0;
  568. res->tv_nsec = (clock_cpu_getres() / (1000UL * 1000));
  569. break;
  570. #endif
  571. default:
  572. res->tv_sec = 0;
  573. res->tv_nsec = 0;
  574. ret = -1;
  575. rt_set_errno(EINVAL);
  576. break;
  577. }
  578. return ret;
  579. #endif /* RT_USING_RTC */
  580. }
  581. RTM_EXPORT(clock_getres);
  582. int clock_gettime(clockid_t clockid, struct timespec *tp)
  583. {
  584. #ifndef RT_USING_RTC
  585. LOG_W(_WARNING_NO_RTC);
  586. return -1;
  587. #else
  588. int ret = 0;
  589. if (tp == RT_NULL)
  590. {
  591. rt_set_errno(EFAULT);
  592. return -1;
  593. }
  594. switch (clockid)
  595. {
  596. case CLOCK_REALTIME:
  597. #ifndef RT_USING_CPUTIME
  598. {
  599. rt_tick_t tick;
  600. rt_base_t level;
  601. level = rt_hw_interrupt_disable();
  602. tick = rt_tick_get(); /* get tick */
  603. tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
  604. tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000U;
  605. rt_hw_interrupt_enable(level);
  606. if (tp->tv_nsec > 1000000000ULL)
  607. {
  608. tp->tv_nsec %= 1000000000ULL;
  609. tp->tv_sec += 1;
  610. }
  611. }
  612. break;
  613. #endif
  614. #ifdef RT_USING_CPUTIME
  615. case CLOCK_MONOTONIC:
  616. case CLOCK_CPUTIME_ID:
  617. {
  618. uint64_t unit = 0;
  619. uint64_t cpu_tick;
  620. unit = clock_cpu_getres();
  621. cpu_tick = clock_cpu_gettime();
  622. tp->tv_sec = ((uint64_t)((cpu_tick * unit) / (1000UL * 1000))) / NANOSECOND_PER_SECOND;
  623. tp->tv_nsec = ((uint64_t)((cpu_tick * unit) / (1000UL * 1000))) % NANOSECOND_PER_SECOND;
  624. }
  625. break;
  626. #endif
  627. default:
  628. tp->tv_sec = 0;
  629. tp->tv_nsec = 0;
  630. rt_set_errno(EINVAL);
  631. ret = -1;
  632. }
  633. return ret;
  634. #endif /* RT_USING_RTC */
  635. }
  636. RTM_EXPORT(clock_gettime);
  637. int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, struct timespec *rmtp)
  638. {
  639. #ifndef RT_USING_RTC
  640. LOG_W(_WARNING_NO_RTC);
  641. return -1;
  642. #else
  643. if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND)
  644. {
  645. rt_set_errno(EINVAL);
  646. return -1;
  647. }
  648. switch (clockid)
  649. {
  650. case CLOCK_REALTIME:
  651. {
  652. rt_tick_t tick, tick_old = rt_tick_get();
  653. if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
  654. {
  655. rt_int64_t ts = ((rqtp->tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND);
  656. rt_int64_t tns = (rqtp->tv_nsec - _timevalue.tv_usec * 1000) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
  657. tick = ts + tns;
  658. rt_tick_t rt_tick = rt_tick_get();
  659. tick = tick < rt_tick ? 0 : tick - rt_tick;
  660. }
  661. else
  662. {
  663. tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)(rqtp->tv_nsec) * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
  664. }
  665. rt_thread_delay(tick);
  666. if (rt_get_errno() == -RT_EINTR)
  667. {
  668. if (rmtp)
  669. {
  670. tick = tick_old + tick - rt_tick_get();
  671. /* get the passed time */
  672. rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
  673. rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
  674. }
  675. rt_set_errno(EINTR);
  676. return -1;
  677. }
  678. }
  679. break;
  680. #ifdef RT_USING_CPUTIME
  681. case CLOCK_MONOTONIC:
  682. case CLOCK_CPUTIME_ID:
  683. {
  684. rt_uint64_t cpu_tick_old = clock_cpu_gettime();
  685. uint64_t unit = clock_cpu_getres();
  686. rt_uint64_t ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
  687. rt_uint64_t tick = (ns * (1000UL * 1000)) / unit;
  688. if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
  689. tick -= cpu_tick_old;
  690. rt_cputime_sleep(tick);
  691. if (rt_get_errno() == -RT_EINTR)
  692. {
  693. if (rmtp)
  694. {
  695. uint64_t rmtp_cpu_tick = tick - clock_cpu_gettime();
  696. rmtp->tv_sec = ((time_t)((rmtp_cpu_tick * unit) / (1000UL * 1000))) / NANOSECOND_PER_SECOND;
  697. rmtp->tv_nsec = ((long)((rmtp_cpu_tick * unit) / (1000UL * 1000))) % NANOSECOND_PER_SECOND;
  698. }
  699. rt_set_errno(EINTR);
  700. return -1;
  701. }
  702. }
  703. break;
  704. #endif
  705. default:
  706. rt_set_errno(EINVAL);
  707. return -1;
  708. }
  709. return 0;
  710. #endif
  711. }
  712. RTM_EXPORT(clock_nanosleep);
  713. int clock_settime(clockid_t clockid, const struct timespec *tp)
  714. {
  715. #ifndef RT_USING_RTC
  716. LOG_W(_WARNING_NO_RTC);
  717. return -1;
  718. #else
  719. rt_base_t level;
  720. int second;
  721. rt_tick_t tick;
  722. rt_device_t device;
  723. if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
  724. {
  725. rt_set_errno(EFAULT);
  726. return -1;
  727. }
  728. /* get second */
  729. second = tp->tv_sec;
  730. level = rt_hw_interrupt_disable();
  731. tick = rt_tick_get(); /* get tick */
  732. /* update timevalue */
  733. _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
  734. _timevalue.tv_sec = second - tick / RT_TICK_PER_SECOND - 1;
  735. rt_hw_interrupt_enable(level);
  736. /* update for RTC device */
  737. device = rt_device_find("rtc");
  738. if (device != RT_NULL)
  739. {
  740. /* set realtime seconds */
  741. if(rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second) == RT_EOK)
  742. {
  743. return 0;
  744. }
  745. }
  746. return -1;
  747. #endif /* RT_USING_RTC */
  748. }
  749. RTM_EXPORT(clock_settime);
  750. int rt_timespec_to_tick(const struct timespec *time)
  751. {
  752. int tick;
  753. int nsecond, second;
  754. struct timespec tp = {0};
  755. RT_ASSERT(time != RT_NULL);
  756. tick = RT_WAITING_FOREVER;
  757. if (time != NULL)
  758. {
  759. /* get current tp */
  760. clock_gettime(CLOCK_REALTIME, &tp);
  761. if ((time->tv_nsec - tp.tv_nsec) < 0)
  762. {
  763. nsecond = NANOSECOND_PER_SECOND - (tp.tv_nsec - time->tv_nsec);
  764. second = time->tv_sec - tp.tv_sec - 1;
  765. }
  766. else
  767. {
  768. nsecond = time->tv_nsec - tp.tv_nsec;
  769. second = time->tv_sec - tp.tv_sec;
  770. }
  771. tick = second * RT_TICK_PER_SECOND + nsecond * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;
  772. if (tick < 0) tick = 0;
  773. }
  774. return tick;
  775. }
  776. RTM_EXPORT(rt_timespec_to_tick);
  777. #endif /* RT_USING_POSIX_CLOCK */
  778. #ifdef RT_USING_POSIX_TIMER
  779. #define ACTIVE 1
  780. #define NOT_ACTIVE 0
  781. struct timer_obj
  782. {
  783. union
  784. {
  785. struct rt_timer timer;
  786. #ifdef RT_USING_CPUTIME
  787. struct rt_cputimer cputimer;
  788. #endif
  789. };
  790. void (*sigev_notify_function)(union sigval val);
  791. union sigval val;
  792. struct timespec interval; /* Reload value */
  793. struct timespec value; /* Reload value */
  794. rt_uint64_t reload; /* Reload value in ms */
  795. rt_uint32_t status;
  796. int sigev_signo;
  797. clockid_t clockid;
  798. #ifdef RT_USING_SMART
  799. pid_t pid;
  800. #endif
  801. };
  802. static void rtthread_timer_wrapper(void *timerobj)
  803. {
  804. struct timer_obj *timer;
  805. timer = (struct timer_obj *)timerobj;
  806. if (timer->reload == 0U)
  807. {
  808. timer->status = NOT_ACTIVE;
  809. }
  810. #ifdef RT_USING_CPUTIME
  811. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  812. {
  813. timer->reload = ((timer->interval.tv_sec * NANOSECOND_PER_SECOND + timer->interval.tv_nsec) * (1000UL * 1000)) / clock_cpu_getres();
  814. if (timer->reload)
  815. rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
  816. }
  817. else
  818. #endif /* RT_USING_CPUTIME */
  819. {
  820. timer->reload = (timer->interval.tv_sec * RT_TICK_PER_SECOND) + (timer->interval.tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
  821. if (timer->reload)
  822. rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
  823. }
  824. #ifdef RT_USING_SMART
  825. sys_kill(timer->pid, timer->sigev_signo);
  826. #else
  827. if(timer->sigev_notify_function != RT_NULL)
  828. {
  829. (timer->sigev_notify_function)(timer->val);
  830. }
  831. #endif
  832. }
  833. #define TIMER_ID_MAX 50
  834. static struct timer_obj *_g_timerid[TIMER_ID_MAX];
  835. static int timerid_idx = 0;
  836. RT_DEFINE_SPINLOCK(_timer_id_lock);
  837. void timer_id_init(void)
  838. {
  839. for (int i = 0; i < TIMER_ID_MAX; i++)
  840. {
  841. _g_timerid[i] = NULL;
  842. }
  843. timerid_idx = 0;
  844. }
  845. int timer_id_alloc(void)
  846. {
  847. for (int i = 0; i < timerid_idx; i++)
  848. {
  849. if (_g_timerid[i] == NULL)
  850. return i;
  851. }
  852. if (timerid_idx < TIMER_ID_MAX)
  853. {
  854. timerid_idx++;
  855. return timerid_idx; /* todo */
  856. }
  857. return -1;
  858. }
  859. void timer_id_lock()
  860. {
  861. rt_hw_spin_lock(&_timer_id_lock);
  862. }
  863. void timer_id_unlock()
  864. {
  865. rt_hw_spin_unlock(&_timer_id_lock);
  866. }
  867. struct timer_obj *timer_id_get(rt_ubase_t timerid)
  868. {
  869. struct timer_obj *timer;
  870. if (timerid < 0 || timerid >= TIMER_ID_MAX)
  871. {
  872. return NULL;
  873. }
  874. timer_id_lock();
  875. if (_g_timerid[timerid] == NULL)
  876. {
  877. timer_id_unlock();
  878. LOG_E("can not find timer!");
  879. return NULL;
  880. }
  881. timer = _g_timerid[timerid];
  882. timer_id_unlock();
  883. return timer;
  884. }
  885. int timer_id_put(int id)
  886. {
  887. if (_g_timerid[id] == NULL)
  888. return -1;
  889. _g_timerid[id] = NULL;
  890. return 0;
  891. }
  892. /**
  893. * @brief Create a per-process timer.
  894. *
  895. * This API does not accept SIGEV_THREAD as valid signal event notification
  896. * type.
  897. *
  898. * See IEEE 1003.1
  899. */
  900. int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
  901. {
  902. static int num = 0;
  903. int _timerid = 0;
  904. struct timer_obj *timer;
  905. char timername[RT_NAME_MAX] = {0};
  906. if (clockid > CLOCK_ID_MAX ||
  907. (evp->sigev_notify != SIGEV_NONE &&
  908. evp->sigev_notify != SIGEV_SIGNAL))
  909. {
  910. rt_set_errno(EINVAL);
  911. return -1;
  912. }
  913. timer = rt_malloc(sizeof(struct timer_obj));
  914. if(timer == RT_NULL)
  915. {
  916. rt_set_errno(ENOMEM);
  917. return -1;
  918. }
  919. rt_snprintf(timername, RT_NAME_MAX, "psx_tm%02d", num++);
  920. num %= 100;
  921. timer->sigev_signo = evp->sigev_signo;
  922. #ifdef RT_USING_SMART
  923. timer->pid = lwp_self()->pid;
  924. #endif
  925. timer->sigev_notify_function = evp->sigev_notify_function;
  926. timer->val = evp->sigev_value;
  927. timer->interval.tv_sec = 0;
  928. timer->interval.tv_nsec = 0;
  929. timer->reload = 0U;
  930. timer->status = NOT_ACTIVE;
  931. timer->clockid = clockid;
  932. #ifdef RT_USING_CPUTIME
  933. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  934. {
  935. rt_cputimer_init(&timer->cputimer, timername, rtthread_timer_wrapper, timer, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
  936. }
  937. else
  938. #endif /* RT_USING_CPUTIME */
  939. {
  940. if (evp->sigev_notify == SIGEV_NONE)
  941. rt_timer_init(&timer->timer, timername, RT_NULL, RT_NULL, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
  942. else
  943. rt_timer_init(&timer->timer, timername, rtthread_timer_wrapper, timer, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
  944. }
  945. timer_id_lock();
  946. _timerid = timer_id_alloc();
  947. if (_timerid < 0)
  948. {
  949. timer_id_unlock();
  950. LOG_E("_timerid overflow!");
  951. return -1; /* todo:memory leak */
  952. }
  953. _g_timerid[_timerid] = timer;
  954. *timerid = (timer_t)(rt_ubase_t)_timerid;
  955. timer_id_unlock();
  956. return 0;
  957. }
  958. RTM_EXPORT(timer_create);
  959. /**
  960. * @brief Delete a per-process timer.
  961. *
  962. * See IEEE 1003.1
  963. */
  964. int timer_delete(timer_t timerid)
  965. {
  966. struct timer_obj *timer;
  967. rt_ubase_t ktimerid;
  968. ktimerid = (rt_ubase_t)timerid;
  969. if (ktimerid < 0 || ktimerid >= TIMER_ID_MAX)
  970. {
  971. rt_set_errno(EINVAL);
  972. return -1;
  973. }
  974. timer_id_lock();
  975. if (_g_timerid[ktimerid] == NULL)
  976. {
  977. timer_id_unlock();
  978. rt_set_errno(EINVAL);
  979. LOG_E("can not find timer!");
  980. return -1;
  981. }
  982. timer = _g_timerid[ktimerid];
  983. timer_id_put(ktimerid);
  984. timer_id_unlock();
  985. if (timer == RT_NULL)
  986. {
  987. rt_set_errno(EINVAL);
  988. return -1;
  989. }
  990. #ifdef RT_USING_CPUTIME
  991. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  992. {
  993. if (timer->status == ACTIVE)
  994. {
  995. timer->status = NOT_ACTIVE;
  996. rt_cputimer_stop(&timer->cputimer);
  997. }
  998. rt_cputimer_detach(&timer->cputimer);
  999. }
  1000. else
  1001. #endif /* RT_USING_CPUTIME */
  1002. {
  1003. if (timer->status == ACTIVE)
  1004. {
  1005. timer->status = NOT_ACTIVE;
  1006. rt_timer_stop(&timer->timer);
  1007. }
  1008. rt_timer_detach(&timer->timer);
  1009. }
  1010. rt_free(timer);
  1011. return 0;
  1012. }
  1013. RTM_EXPORT(timer_delete);
  1014. /**
  1015. *
  1016. * Return the overrun count for the last timer expiration.
  1017. * It is subefficient to create a new structure to get overrun count.
  1018. **/
  1019. int timer_getoverrun(timer_t timerid)
  1020. {
  1021. rt_set_errno(ENOSYS);
  1022. return -1;
  1023. }
  1024. /**
  1025. * @brief Get amount of time left for expiration on a per-process timer.
  1026. *
  1027. * See IEEE 1003.1
  1028. */
  1029. int timer_gettime(timer_t timerid, struct itimerspec *its)
  1030. {
  1031. struct timer_obj *timer;
  1032. rt_uint32_t seconds, nanoseconds;
  1033. timer = timer_id_get((rt_ubase_t)timerid);
  1034. if (timer == NULL)
  1035. {
  1036. rt_set_errno(EINVAL);
  1037. return -1;
  1038. }
  1039. if (its == NULL)
  1040. {
  1041. rt_set_errno(EFAULT);
  1042. return -1;
  1043. }
  1044. if (timer->status == ACTIVE)
  1045. {
  1046. #ifdef RT_USING_CPUTIME
  1047. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  1048. {
  1049. rt_uint64_t remain_tick;
  1050. rt_uint64_t remaining;
  1051. rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_GET_REMAIN_TIME, &remain_tick);
  1052. remaining = ((remain_tick - clock_cpu_gettime()) * (1000UL * 1000)) / clock_cpu_getres();
  1053. seconds = remaining / NANOSECOND_PER_SECOND;
  1054. nanoseconds = remaining % NANOSECOND_PER_SECOND;
  1055. }
  1056. else
  1057. #endif /* RT_USING_CPUTIME */
  1058. {
  1059. rt_tick_t remain_tick;
  1060. rt_tick_t remaining;
  1061. rt_timer_control(&timer->timer, RT_TIMER_CTRL_GET_REMAIN_TIME, &remain_tick);
  1062. /* 'remain_tick' is minimum-unit in the RT-Thread' timer,
  1063. * so the seconds, nanoseconds will be calculated by 'remain_tick'.
  1064. */
  1065. remaining = remain_tick - rt_tick_get();
  1066. /* calculate 'second' */
  1067. seconds = remaining / RT_TICK_PER_SECOND;
  1068. /* calculate 'nanosecond'; To avoid lost of accuracy, because "RT_TICK_PER_SECOND" maybe 100, 1000, 1024 and so on.
  1069. *
  1070. * remain_tick millisecond remain_tick * MILLISECOND_PER_SECOND
  1071. * ------------------------- = -------------------------- ---> millisecond = -------------------------------------------
  1072. * RT_TICK_PER_SECOND MILLISECOND_PER_SECOND RT_TICK_PER_SECOND
  1073. *
  1074. * remain_tick * MILLISECOND_PER_SECOND remain_tick * MILLISECOND_PER_SECOND * MICROSECOND_PER_SECOND
  1075. * millisecond = ---------------------------------------- ---> nanosecond = -------------------------------------------------------------------
  1076. * RT_TICK_PER_SECOND RT_TICK_PER_SECOND
  1077. *
  1078. */
  1079. nanoseconds = (((remaining % RT_TICK_PER_SECOND) * MILLISECOND_PER_SECOND) * MICROSECOND_PER_SECOND) / RT_TICK_PER_SECOND;
  1080. }
  1081. its->it_value.tv_sec = (rt_int32_t)seconds;
  1082. its->it_value.tv_nsec = (rt_int32_t)nanoseconds;
  1083. }
  1084. else
  1085. {
  1086. /* Timer is disarmed */
  1087. its->it_value.tv_sec = 0;
  1088. its->it_value.tv_nsec = 0;
  1089. }
  1090. /* The interval last set by timer_settime() */
  1091. its->it_interval = timer->interval;
  1092. return 0;
  1093. }
  1094. RTM_EXPORT(timer_gettime);
  1095. /**
  1096. * @brief Sets expiration time of per-process timer.
  1097. *
  1098. * See IEEE 1003.1
  1099. */
  1100. int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
  1101. struct itimerspec *ovalue)
  1102. {
  1103. struct timer_obj *timer = timer_id_get((rt_ubase_t)timerid);
  1104. if (timer == NULL ||
  1105. value->it_interval.tv_nsec < 0 ||
  1106. value->it_interval.tv_nsec >= NANOSECOND_PER_SECOND ||
  1107. value->it_interval.tv_sec < 0 ||
  1108. value->it_value.tv_nsec < 0 ||
  1109. value->it_value.tv_nsec >= NANOSECOND_PER_SECOND ||
  1110. value->it_value.tv_sec < 0)
  1111. {
  1112. rt_set_errno(EINVAL);
  1113. return -1;
  1114. }
  1115. /* Save time to expire and old reload value. */
  1116. if (ovalue != NULL)
  1117. {
  1118. timer_gettime(timerid, ovalue);
  1119. }
  1120. /* Stop the timer if the value is 0 */
  1121. if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0))
  1122. {
  1123. if (timer->status == ACTIVE)
  1124. {
  1125. #ifdef RT_USING_CPUTIME
  1126. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  1127. rt_cputimer_stop(&timer->cputimer);
  1128. else
  1129. #endif /* RT_USING_CPUTIME */
  1130. rt_timer_stop(&timer->timer);
  1131. }
  1132. timer->status = NOT_ACTIVE;
  1133. return 0;
  1134. }
  1135. /* calculate timer period(tick); To avoid lost of accuracy, because "RT_TICK_PER_SECOND" maybe 100, 1000, 1024 and so on.
  1136. *
  1137. * tick nanosecond nanosecond * RT_TICK_PER_SECOND
  1138. * ------------------------- = -------------------------- ---> tick = -------------------------------------
  1139. * RT_TICK_PER_SECOND NANOSECOND_PER_SECOND NANOSECOND_PER_SECOND
  1140. *
  1141. */
  1142. #ifdef RT_USING_CPUTIME
  1143. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  1144. {
  1145. rt_uint64_t tick;
  1146. uint64_t unit = clock_cpu_getres();
  1147. tick = ((value->it_value.tv_sec * NANOSECOND_PER_SECOND + value->it_value.tv_nsec) * (1000UL * 1000)) / unit;
  1148. if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
  1149. {
  1150. tick -= clock_cpu_gettime();
  1151. }
  1152. timer->reload = tick;
  1153. }
  1154. else
  1155. #endif /* RT_USING_CPUTIME */
  1156. {
  1157. if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
  1158. {
  1159. #ifndef RT_USING_RTC
  1160. LOG_W(_WARNING_NO_RTC);
  1161. return -1;
  1162. #else
  1163. rt_int64_t ts = ((value->it_value.tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND);
  1164. rt_int64_t tns = (value->it_value.tv_nsec - _timevalue.tv_usec * 1000) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
  1165. rt_int64_t reload = ts + tns;
  1166. rt_tick_t rt_tick = rt_tick_get();
  1167. timer->reload = reload < rt_tick ? 0 : reload - rt_tick;
  1168. #endif
  1169. }
  1170. else
  1171. timer->reload = (value->it_value.tv_sec * RT_TICK_PER_SECOND) + value->it_value.tv_nsec * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
  1172. }
  1173. timer->interval.tv_sec = value->it_interval.tv_sec;
  1174. timer->interval.tv_nsec = value->it_interval.tv_nsec;
  1175. timer->value.tv_sec = value->it_value.tv_sec;
  1176. timer->value.tv_nsec = value->it_value.tv_nsec;
  1177. if (timer->status == ACTIVE)
  1178. {
  1179. #ifdef RT_USING_CPUTIME
  1180. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  1181. rt_cputimer_stop(&timer->cputimer);
  1182. else
  1183. #endif /* RT_USING_CPUTIME */
  1184. rt_timer_stop(&timer->timer);
  1185. }
  1186. timer->status = ACTIVE;
  1187. #ifdef RT_USING_CPUTIME
  1188. if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
  1189. {
  1190. if ((value->it_interval.tv_sec == 0) && (value->it_interval.tv_nsec == 0))
  1191. rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_ONESHOT, RT_NULL);
  1192. else
  1193. rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_PERIODIC, RT_NULL);
  1194. rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
  1195. rt_cputimer_start(&timer->cputimer);
  1196. }
  1197. else
  1198. #endif /* RT_USING_CPUTIME */
  1199. {
  1200. if ((value->it_interval.tv_sec == 0) && (value->it_interval.tv_nsec == 0))
  1201. rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_ONESHOT, RT_NULL);
  1202. else
  1203. rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_PERIODIC, RT_NULL);
  1204. rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
  1205. rt_timer_start(&timer->timer);
  1206. }
  1207. return 0;
  1208. }
  1209. RTM_EXPORT(timer_settime);
  1210. #endif /* RT_USING_POSIX_TIMER */
  1211. /* timezone */
  1212. #ifndef RT_LIBC_DEFAULT_TIMEZONE
  1213. #define RT_LIBC_DEFAULT_TIMEZONE 8
  1214. #endif
  1215. static volatile int8_t _current_timezone = RT_LIBC_DEFAULT_TIMEZONE;
  1216. void tz_set(int8_t tz)
  1217. {
  1218. rt_base_t level;
  1219. level = rt_hw_interrupt_disable();
  1220. _current_timezone = tz;
  1221. rt_hw_interrupt_enable(level);
  1222. }
  1223. int8_t tz_get(void)
  1224. {
  1225. return _current_timezone;
  1226. }
  1227. int8_t tz_is_dst(void)
  1228. {
  1229. return 0;
  1230. }