When applying programming, it is often necessary for a task to perform a specified action after a specific delay, such as waiting for peripherals to ensure reliable data, controlling speaker sound time, and serial communication timeout and re-sending. This requires the use of a timer mechanism to measure the time period of a particular length.
VxWorks, as a real-time embedded system, provides a variety of timing interface functions. The following is a combination of my project experience and on-line reference lists some of the commonly used timing methods, and explain its considerations.
First, Taskdelay
Taskdelay (n) causes the task that invokes the function to delay n ticks (kernel clock cycles). This task voluntarily abandons the CPU within a specified time, except that Taskdelay (0) is dedicated to task scheduling (other tasks that give the CPU the same priority), and task latency is often used to wait for an external event as a timing/delay mechanism. In the absence of interrupt triggering, the Taskdelay can be easily implemented without affecting the overall performance of the system. For example, writing data to Eeprom,eeprom requires an internal erase time (max erase time is l0ms). One tick mentioned below is assumed to be 16. MS (1/60 s). You can simply call Taskdelay (2) To ensure data erasure is complete. Arguably Taskdelay (1) is enough to guarantee why Taskdelay (2) is needed.
This is a flaw used by taskdelay, which needs attention when used. Taskdelay (n) indicates that the task is delayed until the nth system clock arrives at the moment, as shown in 1. If you call Taskdelay (1) at a time with a delay of only 5 ms, then Taskdelay (1) at b time is just a tick cycle. It is necessary to call Taskdelay (2) in order to realize the delay of ten Ms. Taskdelay has an error of nearly 11 ticks, and Taskdelay (n) is actually the time of the delay (n-1) tick~n tick. The delay accuracy is l/n, and the delay of 1s is 1 of the error limit of Taskdelay (60). 6%, and the error limit of Taskdelay (1) will be 100%.
Another thing to note about using Taskdelay is that even after N ticks, a task that invokes a delay is not guaranteed to return to the execution state, and a task with a higher or equal priority may occupy the CPU. Look at 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 the kernel clock frequency * /
- m = 1000/m;
- m = ms/m + 1; /* Taskdelay (N) is actually the time of the delay (n-1) Tick~n*tick * /
- Taskdelay (m);
- }
The following is the Taskdelay delay:
Second, WatchDog
The VxWorks provides a common watchdog timer mechanism. With the provided function, any task can create a watchdog timer that, after a specified delay, is implemented to run the specified program in the context of the system clock ISR. It is important to note that the watchdog timer triggers the program to execute at the interrupt level, rather than in the context of the task. Therefore, the watchdog timed Hook program has a certain limit, the constraint is the same as the Interrupt service program. For example, you cannot use the statement that gets the semaphore, and I/O system functions such as printf ().
A watchdog timer can be created by Wdcreate (). Call Wdstart () to start the timer, the delay parameter is the same as taskdelay in ticks, and you must also specify the program to be called after the timer completes. If your application requires multiple watchdog functions at the same time, you should use Wdcreate () to produce multiple independent watchdog IDs. Because for a given watchdog ID, only one watchdog function can be associated with Wdstart (). To cancel a watchdog timer before the specified tick count arrives, it can be implemented by calling Wdcancel (). Every time Wdstart () is called, the watchdog timer executes only once, so for some applications that require periodic execution, the timer function itself must restart the timer by recursively calling Wdstart ().
If the watchdog timer is used to implement the delay, there is a flaw in the same precision as the taskdelay, with the tick as the benchmark. And the watchdog-related functions are subject to a large limit, which is also an aspect of inconvenient use. However, the task of starting the watchdog is not blocked because the Wdstart () call returns immediately and continues execution.
Third, Sleep/nanosleep
Sleep () and Nanosleep () are the delay function interfaces provided by VxWorks. However, in the actual application, the default is not added, you have to manually add. Sleep in S, Nanosleep can provide more accurate delay, the parameter is the structure of the clock, the parameters can be accurate to NS, but in fact can only be greater than or equal to the time of the question. Because the time base of the Skep or Nanosleep function delay is still tick, the task calling 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 earlier, the Taskdelay (n) Delay time is (n-1) Tick~ntick, while Sleep/nanosleep guarantees that the actual delay time is greater than or equal to the set time parameter. The experiment code is as follows:
[CPP]View Plaincopy
- void Testtimer (int sec,int nsec)
- {
- struct Timespec TM;
- tm.tv_sec = sec;
- tm.tv_nsec = nsec;
- Nanosleep (&tm,null);
- }
Four, high-precision clock systimestamp
Systimestamp () is also called "timestamp". is implemented through the system clock. At first it was also puzzling, the timing of the system clock is tick, how to achieve a high-precision clock it? By reading the BSP underlying code, the Systimestamp actually obtains high-precision timing by reading the current count value of the timer. The frequency of the system timestamp can be obtained through the systimestampfreq () function, which often reflects the reference frequency of the CPU timer. Of course, such a high resolution can only be an ideal value, and different systems may not necessarily be implemented. After all, the time stamp is implemented in a way that has a fatal weakness: by querying. System Clock timing interrupt is in TICB: for the unit, further improve the resolution read Timer count value (CPU of a special function register), can only be the Query method implementation. The code examples are as follows:
- void Msdelay (int ms)
- {
- int t,t1,t2;
- T1 = Systimestamp (); / * Record the previous round of time stamp * /
- do{
- t = 0; / * Count Clear 0 * /
- While (T < Systimestampfreq ()/1000)
- {
- T2 = Systimestamp (); / * Read current time stamp * /
- if (T2 > T1)
- T + = (T2-T1);
- Else
- T + = t2;
- T1 = T2;
- }
- }while (ms--);
- }
This timing method occupies system resources and is only suitable for short time timing, but it is easy to implement. To ensure timing accuracy, you should call Systimestamp in case of lockout interruption, otherwise you should consider using the Systimes-tamplock function.
Five, auxiliary clock
The secondary clock is implemented using another timer (other than the system clock) of the CPU on the target board. It can be flexibly configured to achieve high-resolution timing, and it is easy to achieve MS or even μs-level timing. The VxWorks provides a series of operating interfaces that are the same as the system clock, allowing users to easily hook up their interrupt handling functions, depending on the accuracy of the hardware timer and the length of the user interrupt function. This is the way to use the auxiliary clock as an accurate delay mechanism, such as MS-level delay. The initialization program first calls the Sysauxclkrateset () function to set the secondary clock interrupt period to 1ms (typically in Contig. h file between Aux_clk_rate_min and Aux_clk_rate_max, the interrupt frequency is limited, if necessary can be defined for this macro, and then through the Ysauxclkconneet ()? Connect the user handler function to the secondary clock interrupt, The user handler function can release a synchronous semaphore for semgive (Semtimer). Write a Msdelay (INTMS) as the other task invocation interface, the function code is as follows:
- void Msdelay (int ms)
- {
- int i;
- Sysauxclkenable (); / * Start the secondary timer * /
- For (i = 0;i < ms;i++)
- Semtake (Semtimer); / * Wait for a timed interrupt to release the semaphore * /
- Sysauxclkdisable ();
- }
This method can achieve very precise timing, the task of calling the delay is in the task blocking state. However, there is still a flaw in the use, can not implement multiple tasks at the same time, and need a CPU clock resources, if there is no redundant clock, then this method can not be implemented.
It is also important to note that the Tornado Debugging tool browser A >spychart implementation principle is to use the auxiliary timer to generate interrupts, and record the current interrupted task, the sample data to reflect the CPU utilization of each task. So if a secondary timer is used in the debugger, the timer function will be re-hooked when using the spy chart, and the original timed-hook program will not be performed. Conversely, if the auxiliary timer handler is hooked up after the spy chart is running, the operation of the spy chart will be problematic. The experiment found that when the spy chart was run, the auxiliary timer handler function was re-attached, and the spy chart did not update the task status even if auto Refresh was selected.
The timing interfaces provided by the VxWorks (not necessarily dedicated to timing or indirect implementations) are far more than that. Depending on the accuracy, resource status, and priority requirements, you should use whichever method you want.
Several time-delay methods commonly used under "turn" VxWorks