📄 kernel-clocks.html
字号:
<!-- Copyright (C) 2003 Red Hat, Inc. --><!-- This material may be distributed only subject to the terms --><!-- and conditions set forth in the Open Publication License, v1.0 --><!-- or later (the latest version is presently available at --><!-- http://www.opencontent.org/openpub/). --><!-- Distribution of the work or derivative of the work in any --><!-- standard (paper) book form is prohibited unless prior --><!-- permission is obtained from the copyright holder. --><HTML><HEAD><TITLE>Clocks</TITLE><meta name="MSSmartTagsPreventParsing" content="TRUE"><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="eCos Reference Manual"HREF="ecos-ref.html"><LINKREL="UP"TITLE="The eCos Kernel"HREF="kernel.html"><LINKREL="PREVIOUS"TITLE="Counters"HREF="kernel-counters.html"><LINKREL="NEXT"TITLE="Alarms"HREF="kernel-alarms.html"></HEAD><BODYCLASS="REFENTRY"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">eCos Reference Manual</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="kernel-counters.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="kernel-alarms.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><H1><ANAME="KERNEL-CLOCKS">Clocks</H1><DIVCLASS="REFNAMEDIV"><ANAME="AEN922"></A><H2>Name</H2>cyg_clock_create, cyg_clock_delete, cyg_clock_to_counter, cyg_clock_set_resolution, cyg_clock_get_resolution, cyg_real_time_clock, cyg_current_time -- Provide system clocks</DIV><DIVCLASS="REFSYNOPSISDIV"><ANAME="AEN931"><H2>Synopsis</H2><DIVCLASS="FUNCSYNOPSIS"><ANAME="AEN932"><P></P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="FUNCSYNOPSISINFO">#include <cyg/kernel/kapi.h> </PRE></TD></TR></TABLE><P><CODE><CODECLASS="FUNCDEF">void cyg_clock_create</CODE>(cyg_resolution_t resolution, cyg_handle_t* handle, cyg_clock* clock);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_clock_delete</CODE>(cyg_handle_t clock);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_clock_to_counter</CODE>(cyg_handle_t clock, cyg_handle_t* counter);</CODE></P><P><CODE><CODECLASS="FUNCDEF">void cyg_clock_set_resolution</CODE>(cyg_handle_t clock, cyg_resolution_t resolution);</CODE></P><P><CODE><CODECLASS="FUNCDEF">cyg_resolution_t cyg_clock_get_resolution</CODE>(cyg_handle_t clock);</CODE></P><P><CODE><CODECLASS="FUNCDEF">cyg_handle_t cyg_real_time_clock</CODE>(void);</CODE></P><P><CODE><CODECLASS="FUNCDEF">cyg_tick_count_t cyg_current_time</CODE>(void);</CODE></P><P></P></DIV></DIV><DIVCLASS="REFSECT1"><ANAME="KERNEL-CLOCKS-DESCRIPTION"></A><H2>Description</H2><P>In the eCos kernel clock objects are a special form of <AHREF="kernel-counters.html">counter</A> objects. They are attached toa specific type of hardware, clocks that generate ticks at veryspecific time intervals, whereas counters can be used with any eventsource. </P><P>In a default configuration the kernel provides a single clockinstance, the real-time clock. This gets used for timeslicing and foroperations that involve a timeout, for example<TTCLASS="FUNCTION">cyg_semaphore_timed_wait</TT>. If this functionalityis not required it can be removed from the system using theconfiguration option <TTCLASS="VARNAME">CYGVAR_KERNEL_COUNTERS_CLOCK</TT>.Otherwise the real-time clock can be accessed by a call to<TTCLASS="FUNCTION">cyg_real_time_clock</TT>, allowing applications toattach alarms, and the current counter value can be obtained using<TTCLASS="FUNCTION">cyg_current_time</TT>. </P><P>Applications can create and destroy additional clocks if desired,using <TTCLASS="FUNCTION">cyg_clock_create</TT> and<TTCLASS="FUNCTION">cyg_clock_delete</TT>. The first argument to<TTCLASS="FUNCTION">cyg_clock_create</TT> specifies the<AHREF="kernel-clocks.html#KERNEL-CLOCKS-RESOLUTION">resolution</A> this clockwill run at. The second argument is used to return a handle for thisclock object, and the third argument provides the kernel with thememory needed to hold this object. This clock will not actually tickby itself. Instead it is the responsibility of application code toinitialize a suitable hardware timer to generate interrupts at theappropriate frequency, install an interrupt handler for this, andcall <TTCLASS="FUNCTION">cyg_counter_tick</TT> from inside the DSR.Associated with each clock is a kernel counter, a handle for which canbe obtained using <TTCLASS="FUNCTION">cyg_clock_to_counter</TT>. </P></DIV><DIVCLASS="REFSECT1"><ANAME="KERNEL-CLOCKS-RESOLUTION"></A><H2>Clock Resolutions and Ticks</H2><P>At the kernel level all clock-related operations including delays,timeouts and alarms work in units of clock ticks, rather than in unitsof seconds or milliseconds. If the calling code, whether theapplication or some other package, needs to operate using units suchas milliseconds then it has to convert from these units to clockticks. </P><P>The main reason for this is that it accurately reflects thehardware: calling something like <TTCLASS="FUNCTION">nanosleep</TT> with adelay of ten nanoseconds will not work as intended on any realhardware because timer interrupts simply will not happen thatfrequently; instead calling <TTCLASS="FUNCTION">cyg_thread_delay</TT> withthe equivalent delay of 0 ticks gives a much clearer indication thatthe application is attempting something inappropriate for the targethardware. Similarly, passing a delay of five ticks to<TTCLASS="FUNCTION">cyg_thread_delay</TT> makes it fairly obvious thatthe current thread will be suspended for somewhere between four andfive clock periods, as opposed to passing 50000000 to<TTCLASS="FUNCTION">nanosleep</TT> which suggests a granularity that isnot actually provided. </P><P>A secondary reason is that conversion between clock ticks and unitssuch as milliseconds can be somewhat expensive, and whenever possibleshould be done at compile-time or by the application developer ratherthan at run-time. This saves code size and cpu cycles. </P><P>The information needed to perform these conversions is the clockresolution. This is a structure with two fields, a dividend and adivisor, and specifies the number of nanoseconds between clock ticks.For example a clock that runs at 100Hz will have 10 millisecondsbetween clock ticks, or 10000000 nanoseconds. The ratio between theresolution's dividend and divisor will therefore be 10000000 to 1, andtypical values for these might be 1000000000 and 100. If the clockruns at a different frequency, say 60Hz, the numbers could be1000000000 and 60 respectively. Given a delay in nanoseconds, this canbe converted to clock ticks by multiplying with the the divisor andthen dividing by the dividend. For example a delay of 50 millisecondscorresponds to 50000000 nanoseconds, and with a clock frequency of100Hz this can be converted to((50000000 * 100) / 1000000000) = 5clock ticks. Given the large numbers involved this arithmetic normallyhas to be done using 64-bit precision and the<SPANCLASS="TYPE">long long</SPAN> data type, but allows code to run onhardware with unusual clock frequencies. </P><P>The default frequency for the real-time clock on any platform isusually about 100Hz, but platform-specific documentation should beconsulted for this information. Usually it is possible to overridethis default by configuration options, but again this depends on thecapabilities of the underlying hardware. The resolution for any clockcan be obtained using <TTCLASS="FUNCTION">cyg_clock_get_resolution</TT>.For clocks created by application code, there is also a function<TTCLASS="FUNCTION">cyg_clock_set_resolution</TT>. This does not affectthe underlying hardware timer in any way, it merely updates theinformation that will be returned in subsequent calls to<TTCLASS="FUNCTION">cyg_clock_get_resolution</TT>: changing the actualunderlying clock frequency will require appropriate manipulation ofthe timer hardware. </P></DIV><DIVCLASS="REFSECT1"><ANAME="KERNEL-CLOCKS-CONTEXT"></A><H2>Valid contexts</H2><P><TTCLASS="FUNCTION">cyg_clock_create</TT> is usually only called duringsystem initialization (if at all), but may also be called from threadcontext. The same applies to <TTCLASS="FUNCTION">cyg_clock_delete</TT>.The remaining functions may be called during initialization, fromthread context, or from DSR context, although it should be noted thatthere is no locking between<TTCLASS="FUNCTION">cyg_clock_get_resolution</TT> and<TTCLASS="FUNCTION">cyg_clock_set_resolution</TT> so theoretically it ispossible that the former returns an inconsistent data structure. </P></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="kernel-counters.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="ecos-ref.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="kernel-alarms.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Counters</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="kernel.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Alarms</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -