Sender: gdtyy (gdtyy), email area: embedded
Subject: Lecture 10 Time Management
Mailing station: shuimu community (Mon Jun 25 23:36:06 2007), within the station
*******************
* Lecture 10 Time Management *
*******************
Asdjf@163.com www.armecos.com
Time management is an important function of the operating system. The hardware must provide a periodic clock or timer
Time-related functional components in the system are supported. Generally, most CPUs have one or more built-in timers, providing weekly
Phase interruption, even if there is no built-in timer, you must also use an external timer or clock.
ECos abstracts the nature of time-related hardware and provides a general time management mechanism. These timing mechanisms include:
Counter, clock, alarm, and timer ). With these abstract concepts, we
You don't have to do repetitive work on the shelf, or waste time on hardware details, but concentrate on functions.
Implementation. The advantage of Interface Programming for abstract platforms is that it is portable and should not be changed.
Counter --- monotonically increases the Count of specified events.
Clock-a counter that counts a certain period of time tick (tick ).
Warning Device-adds a prompt mechanism based on the counter, or generates a prompt function based on the counter value.
Periodic events.
Timer-a warning device that is simply appended to the clock.
These time-related API functions are defined in <Cyg/kernel/KAPI. h>. This header file must be included during use.
============
* Counter *
============
Create
Void cyg_counter_create (cyg_handle_t * handle, cyg_handle_t * counter)
This function creates a personalized counter, and the new Counter handle is returned through handle.
Cyg_handle_t --- Cyg indicates the definition of Cygnus. Handle is the handle, and T is the abbreviation of type.
It means the handle type defined by Cygnus. All counter functions are cyg_counter
As long as you see counter, you will know that it is related to the counter.
Counter is the memory that the application provides to the counter, thus reducing the dynamic memory score in the kernel.
Configuration Requirements. Many functions in ECOs are used by the application to provide the memory required for the target object, instead of static memory allocation.
Is Dynamic Allocation in line with the characteristics of embedded systems.
Delete
Void cyg_counter_delete (cyg_handle_t counter)
Reads the current value of a specified counter.
Cyg_tick_count_t cyg_counter_current_value (cyg_handle_t counter)
Set the Specified Counter Value
Void cyg_counter_set_value (cyg_handle_t counter, cyg_tick_count_t new_value)
Counter plus 1
Void cyg_counter_tick (cyg_handle_t counter)
Creating a new counter does not automatically connect the event source to the counter, regardless of the corresponding time
You must call the cyg_counter_tick function to increase the counter count by 1. This function is generally called in the DSR of an event interruption.
.
Increase the number of specified tick counters
Void cyg_counter_multi_tick (cyg_handle_t counter, cyg_tick_count_t ticks)
==========
* Clock *
==========
All kernel-level clock-related operations, including latency, timeout, and alarms, are performed in the unit of clock tick.
Instead of in seconds or microseconds. If the application or other software requires a time order such as seconds or microseconds
The unit of time must be converted to a tick. This is because only the tick of the clock can accurately reflect the hardware.
. In addition, if the time unit in the traditional sense is used, such as the nanosecond (NS), the hardware may not be able to provide support.
. Another reason is that the conversion between the clock tick and the traditional time unit wastes a lot of code and data,
The unit of clock tick can save the amount of code and CPU time.
The conversion between clock Units requires a resolution. For example, if a clock runs at 100Hz, tick is generated within one second.
Resolution rate: 1000000000 (NS): 100 (tick ). Similarly, the resolution of 60Hz is 1000000000: 60.
By dividing the latency in the unit of nanoseconds by the resolution, you can convert it to the corresponding clock tick. For example, a 50 ms delay
Time (50000000ns), the clock frequency is 100Hz (that is, the resolution is 1000000000: 100), you can use the following
Convert to clock tick:
50000000 bytes (1000000000/100) = 5
That is, 50 ms latency corresponds to 5 tick at Hz clock resolution.
Create
Void cyg_clock_create (cyg_resolution_t resolution, cyg_handle_t * handle,
Cyg_clock * Clock)
Create a new clock with the given resolution. The handle of the new clock is taken back by handle.
Delete
Void cyg_clock_delete (cyg_handle_t clock)
Before calling this function, make sure that the system has no components that use the clock.
Convert a clock to a counter
Void cyg_clock_to_counter (cyg_handle_t clock, cyg_handle_t * counter)
Set clock resolution
Void cyg_clock_set_resolution (cyg_handle_t clock, cyg_resolution_t
Resolution)
Get clock resolution
Cyg_resolution_t cyg_clock_get_resolution (cyg_handle_t clock)
Obtain the system's real-time clock (RTC, not external RTC, is the kernel's abstract clock)
Cyg_handle_t cyg_real_time_clock (void)
Obtain the current system time, in the unit of clock tick. The system time is represented by a 64-bit number.
Cyg_tick_count_t cyg_current_time (void)
============
* Warning tool *
============
The kernel warning tool is used with the counter so that a response is taken when a certain number of times occurs.
If the clock is used together with the counter, then when the number of time ticking reaches the appropriate value, that is, at a certain time
An alarm will occur after the cycle.
Create
Void cyg_alarm_create
(
Cyg_handle_t counter, // counter used together with the alert Server
Cyg_alarm_t * alarmfn, // callback function when an alarm is triggered
Cyg_addrword_t data, // parameters passed to the callback function
Cyg_handle_t * handle, // The returned alert handle
Cyg_alarm * Alarm // alert object
)
The callback function Format of alarmfn is as follows:
Void alarm_fun (cyg_handle_t alarm, cyg_addrword_t data)
{
......
}
Delete
Void cyg_alarm_delete (cyg_handle_t alarm)
Initialize and start an alert Server
Void cyg_alarm_initialize
(
Cyg_handle_t alarm, // alert handle
Cyg_tick_count_t trigger, // absolute trigger time
Cyg_tick_count_t interval // trigger Interval
)
Returns the absolute time interval between the next trigger of the alert server and its trigger.
Void cyg_alarm_get_times
(
Cyg_handle_t alarm, // handle of the alert server to be queried
Cyg_tick_count_t trigger, // the absolute time of the next trigger
Cyg_tick_count_t interval // current trigger Interval
)
Enable alerts
Void cyg_alarm_enable (cyg_handle_t alarm)
Warning prohibited
Void cyg_alarm_disable (cyg_handle_t alarm)
========================================================== ==========================================================
==============
Next we will use a specific experiment to describe the usage of time-related API functions.
Use the clock function to count the execution time of the program, which is called before and after the program starts to run.
Cyg_current_time: Get the start time and end time. Convert the unit of tick to the unit of milliseconds.
Number of execution cycles and execution time of a single loop.
Enable the buzzer to voice and mute in a cycle of 2 seconds.
Note: The time obtained by cyg_current_time is 64-bit. When printf displays a 64-bit integer, use the "% LLD" format.
("I64d" is used in msvc). Do not use the printf function in the alert server callback function.
The result of testing smartarm2200 is (cycle 0x195527.8 times): cycles are executed per second, and each cycle is executed.
The time is 5us. The buzzer rings for 2 seconds and stops for 2 seconds.
The result of the easyarm2200 test is (0x344926.3 cycles): cycles are executed per second.
3us.
It can be seen that easyarm2200 is faster than smartarm2200, because the former uses SRAM than the latter.
Psram is fast.
With time-related functions, we can regularly execute some tasks and calculate bit rates. For example
It is easier to insert I frames at regular intervals and control the code source rate ......
// Test the program
# Include <Cyg/kernel/KAPI. h>
# Include <Cyg/hal/hal_io.h>
# Include <Cyg/hal/plf_io.h>
# Define stack_size 4096
# Define alarm_interval 200 // 2 seconds
# Define beepcon 0x0000080
# Define loopnum 0x80000
Char stack [stack_size];
Static cyg_thread thread_data;
Static cyg_handle_t thread_handle;
Cyg_handle_t counter_handle;
Cyg_handle_t alarm_handle;
Cyg_alarm alarm_object;
Void alarm_func (cyg_handle_t alarm_handle, cyg_addrword_t data)
{
Int I;
Hal_read_uint32 (lpc2xxx_gpio_io0set, I );
If (I & beepcon) = 0)
{
Hal_write_uint32 (lpc2xxx_gpio_io0set, beepcon );
}
Else
{
Hal_write_uint32 (lpc2xxx_gpio_io0clr, beepcon );
}
}
Void
Alarm (cyg_addrword_t data)
{
Cyg_tick_count_t T1, T2, T;
Int I, sum;
Printf ("/n ");
Printf ("/T ******************************/N ");
Printf ("/T * hello! Alarm test. */N ");
Printf ("/T ******************************/n /n ");
Printf ("test speed:/N ");
Sum = 0;
T1 = cyg_current_time ();
For (I = 0; I <loopnum; I ++)
{
Sum = sum + I;
}
T2 = cyg_current_time ();
T = ABS (t2-t1) * 10;
Printf ("START = % LLD/nend = % LLD/N", T1, T2 );
Printf ("Total time = % lldms/N", t );
Printf ("Total loop = % LLD/N", loopnum );
If (t = 0)
{
T = 1;
}
Printf ("% lf (loop/sec), % lf (SEC/loop)/n", loopnum * 1000.0/T, T/1000.0
/Loopnum );
// Set the output to beep
Hal_write_uint32 (lpc2xxx_gpio_io0dir, beepcon );
// Beep is disabled at the beginning, and the default output for power-on is low, resulting in a tweet at the beginning.
Hal_write_uint32 (lpc2xxx_gpio_io0set, beepcon );
// Convert the clock to a counter. The cyg_real_time_clock () function obtains the system real-time clock (RTC ). Real-time
Clock is used for system latency, blocking wait, and other operations.
Cyg_clock_to_counter (cyg_real_time_clock (), & counter_handle );
// Create an alert Server
Cyg_alarm_create (counter_handle, alarm_func, 0, & alarm_handle,
& Alarm_object );
// Initialize the alert Server
Cyg_alarm_initialize (alarm_handle, cyg_current_time () + alarm_interval,
Alarm_interval );
// Enable alerts
Cyg_alarm_enable (alarm_handle );
While (1)
{
Cyg_thread_delay (2000 );
}
}
Void
Cyg_start (void)
{
// Create a main thread, so we can run the schedpass and have time 'pass'
Cyg_thread_create (10, // priority-just a number
Alarm, // entry
0, // entry Parameter
"Alarm", // name
& Stack, // Stack
Stack_size, // size
& Thread_handle, // handle
& Thread_data // thread Data Structure
);
Cyg_thread_resume (thread_handle); // start it
Cyg_scheduler_start ();
}
--
※Source: · Shui Mu community http://newsmth.net · [from: 61.149.56. *]