During application programming, a task usually needs to execute a specified action after a specific delay, such as waiting for peripherals to ensure data reliability, control speaker voice time and serial communication timeout and resend. This requires the timer mechanism to measure a specific length of time.
As a real-time embedded system, VxWorks provides various timing interface functions. The following describes some common timing methods based on my project experience and online references, and describes the precautions.
I. taskdelay
Taskdelay (n) delays the task calling this function by N tick (kernel clock cycle ). This task voluntarily abandons the CPU at the specified time, except that taskdelay (0) is dedicated to task scheduling (giving the CPU to other tasks with the same priority, task latency is also commonly used to wait for an external event as a timing/latency mechanism. Taskdelay can be easily implemented when no interruption is triggered without affecting the overall system performance. For example, when writing data to the EEPROM, The eeprom requires an internal erasure time (the maximum erasure time is l0ms ). One of the following tick is assumed to be 16.67
MS (1/60 S ). Taskdelay (2) can be called to ensure that data is erased. It is reasonable to say that taskdelay (1) is sufficient to guarantee. Why does taskdelay (2) need to be used?
This is a defect in taskdelay. You need to pay attention to it during use. Taskdelay (n) indicates the time when the task is delayed to the arrival of the nth system clock, as shown in 1. If taskdelay (1) is called at moment a to delay only 5 MS, then taskdelay (1) at moment B is exactly a tick cycle. It can be seen that a latency of 10 ms is required to call taskdelay (2. Taskdelay has an error similar to one tick. taskdelay (n) is actually a latency (n-1) Tick ~ N
Tick time. The delay precision is L/N, and the 1 s delay is the error limit of taskdelay (60) is 1.6%, while the error limit of taskdelay (1) is 100%.
When using taskdelay, you must note that even after N tick tasks, delayed tasks cannot be called and the execution status is returned. tasks with higher or higher priorities may occupy the CPU. After reading the above introduction, you can use it to simulate the sleep function. The Code is as follows:
St_void smssleep (st_long MS) {int M = sysclkrateget ();/* Get kernel clock frequency */M = 1000/m; M = MS/m + 1; /* taskdelay (n) is actually a latency (n-1) Tick ~ N * tick time */taskdelay (m );}
The latency of taskdelay is as follows:
Ii. Watchdog
VxWorks provides a general watchdog timer mechanism. With the provided functions, any task can create a watchdog timer. After a specified delay, the specified program can be run in the context of the system clock ISR. It should be noted that the program regularly triggered by the watchdog is executed at the interrupt level, rather than in the context of the task. Therefore, there are some restrictions on the preparation of programs mounted by the watchdog on a regular basis. The restrictions are the same as those for the interruption of service programs. For example, you cannot use a statement to obtain a semaphore or an I/O system function like printf.
You can use wdcreate () to create a watchdog timer. Call wdstart () to start the timer. The latency parameter is tick as the taskdelay parameter, and the program to be called after the timer is completed must also be specified. If the application requires multiple watchdog functions at the same time, wdcreate () should be used to generate multiple independent watchdog IDs. For a given watchdog ID, only one watchdog function can be associated through wdstart. To cancel a watchdog timer before the specified tick count reaches, you can call wdcancel. Every time wdstart () is called, the watchdog timer is executed only once. Therefore, for applications that require periodic execution, the timer function must call wdstart () recursively () to restart the timer.
If the watchdog timer is used to implement latency, there is a defect with the same precision as taskdelay, which is based on tick. in addition, the function associated with the watchdog has a lot of restrictions, which is also an inconvenient aspect of use. However, the task of starting the watchdog will not be blocked because the wdstart () call returns immediately and continues execution.
Iii. Sleep/nanosleep
Sleep () and nanosleep () are the latency function interfaces provided by VxWorks. However, in actual applications, it is not added by default and must be manually added. Sleep is measured in seconds. nanosleep can provide more precise latency. parameter passing is the structure of the clock, and the parameter can be precise to NS, but in fact it can only be greater than or equal to this time. Because the latency of the Skep or nanosleep function is still tick, the task that calls this function is in the task delay state, which is consistent with taskdelay. The difference is that taskdelay () is used for task scheduling, taskdelay (o) has its own meaning, and sleep (o) is meaningless. As mentioned above, the taskdelay (n) latency is (n-1) Tick ~ Ntick, while sleep/nanosleep ensures that the actual delay time is greater than or equal to the set time parameter. The experiment code is as follows:
void testTimer(int sec,int nsec){struct timespec tm;tm.tv_sec = sec;tm.tv_nsec = nsec;nanosleep(&tm,NULL);}
Iv. High-precision clock speed imestamp
Systimestamp () is also called "timestamp ". It is implemented through the system clock. At the beginning, I was puzzled. The scheduled cycle of the system clock is tick. How can I implement a high-precision clock? By reading the underlying BSP code, it is found that the systimestamp actually obtains high-precision timing by reading the current Count value of the timer. The systimestampfreq () function can obtain the frequency of the system timestamp, which often reflects the benchmark frequency of the CPU timer. Of course, such a high resolution can only be an ideal value, not necessarily achieved by different systems. After all, the implementation of the timestamp has a fatal weakness: the query method. The scheduled interruption of the system clock is in the unit of ticb: to further improve the resolution read timer Count value (a special function register of the CPU), which can only be implemented in the query mode. The sample code is as follows:
Void msdelay (int ms) {int T, T1, T2; T1 = systimestamp ();/* record the timestamp of the previous round */do {T = 0; /* counting cleared */while (T <systimestampfreq ()/1000) {t2 = systimestamp ();/* read the current timestamp */If (T2> T1) T + = (t2-t1); elset + = t2; T1 = t2;} while (MS --);}
This method occupies system resources and is only applicable to short-term timing, but easy to implement. To ensure timing accuracy, call the systimestamp when the lock is interrupted; otherwise, use the systimes-tamplock function.
5. Auxiliary clock
The secondary clock is interrupted by another timer (except the system clock) of the CPU on the target board. It can be flexibly configured to implement high-resolution timing and easily implement MS-level or even μs-level timing. VxWorks provides a series of Operation interfaces that are the same as the system clock. You can easily mount your interrupt processing functions. The clock resolution depends on the accuracy of the hardware timer and the length of the interrupt function. The secondary clock can be used as a precise latency mechanism (such as MS-level latency. The initialization program first calls the sysauxclkrateset () function to set the auxiliary clock interruption period to 1 ms (generally in contig. in the hfile, the frequency of interruption is limited between aux_clk_rate_min and aux_clk_rate_max. If necessary, you can modify the macro definition), and then use ysauxclkconneet ()? Connect the user processing function to the secondary clock interruption. The user processing function can release a synchronous semaphore for semgive (semtimer. Compile an msdelay (intms) interface to call other tasks. The function code is as follows:
Void msdelay (int ms) {int I; sysauxclkenable ();/* enable secondary timer */for (I = 0; I <MS; I ++) semtake (semtimer ); /* Wait for timed interruption to release the semaphores */sysauxclkdisable ();}
This method can implement very accurate timing, and the delayed call task is in the task blocking state. However, there are still defects in use, so that multiple tasks cannot be called at the same time and a CPU clock resource is required. If there is no redundant clock, this method cannot be implemented.
Note that browser 1> spychart, the debugging tool of tornado, uses the auxiliary timer to generate interruptions and record the interrupted tasks, the sampling data reflects the CPU usage of each task. Therefore, if the secondary timer is used in the debugging program, the timer processing function will be re-mounted when the spy chart is used, and the original timer mounting program will not be available. If the secondary scheduled processing function is attached after spy chart is run, spy chart runs incorrectly. The experiment found that running spy
The secondary timer processing function is attached after the chart. Even if the selected spy chart is automatically refreshed, the status of each task is not updated.
The timing interface provided by VxWorks (not necessarily used for timing or indirectly) is far more than that. The specific method should be determined based on its precision, resource status, and priority requirements.