2 * Amazon FreeRTOS POSIX V1.1.0
\r
3 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://aws.amazon.com/freertos
\r
23 * http://www.FreeRTOS.org
\r
27 * @file FreeRTOS_POSIX_clock.c
\r
28 * @brief Implementation of clock functions in time.h
\r
31 /* C standard library includes. */
\r
35 /* FreeRTOS+POSIX includes. */
\r
36 #include "FreeRTOS_POSIX.h"
\r
37 #include "FreeRTOS_POSIX/errno.h"
\r
38 #include "FreeRTOS_POSIX/time.h"
\r
39 #include "FreeRTOS_POSIX/utils.h"
\r
41 /* Declaration of snprintf. The header stdio.h is not included because it
\r
42 * includes conflicting symbols on some platforms. */
\r
43 extern int snprintf( char * s,
\r
45 const char * format,
\r
48 /*-----------------------------------------------------------*/
\r
50 clock_t clock( void )
\r
52 /* This function is currently unsupported. It will always return -1. */
\r
54 return ( clock_t ) -1;
\r
57 /*-----------------------------------------------------------*/
\r
59 int clock_getcpuclockid( pid_t pid,
\r
60 clockid_t * clock_id )
\r
62 /* Silence warnings about unused parameters. */
\r
66 /* This function is currently unsupported. It will always return EPERM. */
\r
70 /*-----------------------------------------------------------*/
\r
72 int clock_getres( clockid_t clock_id,
\r
73 struct timespec * res )
\r
75 /* Silence warnings about unused parameters. */
\r
78 /* Convert FreeRTOS tick resolution as timespec. */
\r
82 res->tv_nsec = NANOSECONDS_PER_TICK;
\r
88 /*-----------------------------------------------------------*/
\r
90 int clock_gettime( clockid_t clock_id,
\r
91 struct timespec * tp )
\r
93 TimeOut_t xCurrentTime = { 0 };
\r
95 /* Intermediate variable used to convert TimeOut_t to struct timespec.
\r
96 * Also used to detect overflow issues. It must be unsigned because the
\r
97 * behavior of signed integer overflow is undefined. */
\r
98 uint64_t ullTickCount = 0ULL;
\r
100 /* Silence warnings about unused parameters. */
\r
103 /* Get the current tick count and overflow count. vTaskSetTimeOutState()
\r
104 * is used to get these values because they are both static in tasks.c. */
\r
105 vTaskSetTimeOutState( &xCurrentTime );
\r
107 /* Adjust the tick count for the number of times a TickType_t has overflowed.
\r
108 * portMAX_DELAY should be the maximum value of a TickType_t. */
\r
109 ullTickCount = ( uint64_t ) ( xCurrentTime.xOverflowCount ) << ( sizeof( TickType_t ) * 8 );
\r
111 /* Add the current tick count. */
\r
112 ullTickCount += xCurrentTime.xTimeOnEntering;
\r
114 /* Convert ullTickCount to timespec. */
\r
115 UTILS_NanosecondsToTimespec( ( int64_t ) ullTickCount * NANOSECONDS_PER_TICK, tp );
\r
120 /*-----------------------------------------------------------*/
\r
122 int clock_nanosleep( clockid_t clock_id,
\r
124 const struct timespec * rqtp,
\r
125 struct timespec * rmtp )
\r
128 TickType_t xSleepTime = 0;
\r
129 struct timespec xCurrentTime = { 0 };
\r
131 /* Silence warnings about unused parameters. */
\r
134 ( void ) flags; /* This is only ignored if INCLUDE_vTaskDelayUntil is 0. */
\r
137 if( UTILS_ValidateTimespec( rqtp ) == false )
\r
142 /* Get current time */
\r
143 if( ( iStatus == 0 ) && ( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 ) )
\r
150 /* Check for absolute time sleep. */
\r
151 if( ( flags & TIMER_ABSTIME ) == TIMER_ABSTIME )
\r
153 /* Get current time */
\r
154 if( clock_gettime( CLOCK_REALTIME, &xCurrentTime ) != 0 )
\r
159 /* Get number of ticks until absolute time. */
\r
160 if( ( iStatus == 0 ) && ( UTILS_AbsoluteTimespecToDeltaTicks( rqtp, &xCurrentTime, &xSleepTime ) == 0 ) )
\r
162 /* Delay until absolute time if vTaskDelayUntil is available. */
\r
163 #if ( INCLUDE_vTaskDelayUntil == 1 )
\r
165 /* Get the current tick count. This variable isn't declared
\r
166 * at the top of the function because it's only used and needed
\r
167 * if vTaskDelayUntil is available. */
\r
168 TickType_t xCurrentTicks = xTaskGetTickCount();
\r
170 /* Delay until absolute time. */
\r
171 vTaskDelayUntil( &xCurrentTicks, xSleepTime );
\r
174 /* If vTaskDelayUntil isn't available, ignore the TIMER_ABSTIME flag
\r
175 * and sleep for a relative time. */
\r
176 vTaskDelay( xSleepTime );
\r
182 /* If TIMER_ABSTIME isn't specified, convert rqtp to ticks and
\r
183 * sleep for a relative time. */
\r
184 if( UTILS_TimespecToTicks( rqtp, &xSleepTime ) == 0 )
\r
186 vTaskDelay( xSleepTime );
\r
194 /*-----------------------------------------------------------*/
\r
196 int clock_settime( clockid_t clock_id,
\r
197 const struct timespec * tp )
\r
199 /* Silence warnings about unused parameters. */
\r
203 /* This function is currently unsupported. It will always return -1 and
\r
204 * set errno to EPERM. */
\r
210 /*-----------------------------------------------------------*/
\r
212 int nanosleep( const struct timespec * rqtp,
\r
213 struct timespec * rmtp )
\r
216 TickType_t xSleepTime = 0;
\r
218 /* Silence warnings about unused parameters. */
\r
222 if( UTILS_ValidateTimespec( rqtp ) == false )
\r
230 /* Convert rqtp to ticks and delay. */
\r
231 if( UTILS_TimespecToTicks( rqtp, &xSleepTime ) == 0 )
\r
233 vTaskDelay( xSleepTime );
\r
240 /*-----------------------------------------------------------*/
\r