[Deven] improvement on the timer in uCOS-II

Source: Internet
Author: User

[Deven] improvement on the timer in uCOS-II
Author: Deven
Deven.yculblog.com

Hardware environment: lpc2220; the keyboard uses zlg7290, the interrupt signal is connected to eint3, And the IIC is used to read the key data; the encoder uses 1000 signals, z is connected to eint0, A is connected to cap1.2, B is connected to cap1.3.

I. What is the problem?
I don't know why I post a semaphore in the key interrupt. Although I got a response in the task, I found that after switching to the task, I did not execute it, but kept entering timer0 for interruption. Latency in keyboard response can be tolerated, but other interruptions may affect system performance. For example, when I use a photoelectric encoder, the signal is triggered frequently, and the actual response from the interruption to the task slows down.
In order to respond to tasks in a timely manner and reduce the frequency of Interrupt triggering, the system timer must be improved.

II. Functions of clock interruption
When we first saw that the clock was interrupted, we took it for granted that the task was necessary for Operating System Scheduling. After further consideration, we found that the task was wrong. In a common time-based system, in order to rotate the time slice, the processor must be switched to the next task after a certain period of time. Therefore, a timer must be provided to switch the task periodically. In a priority scheduling system such as uCOS-II, a high-priority task is scheduled to enter a low-priority task only after the CPU is abandoned.
In the uCOS-II system, what role does clock interruption play? First, let's take a look at the circumstances under which the task gave up the CPU and under which the CPU was obtained.
The CPU discard function can be triggered by ossempend, osmutexpend, osflagpend, osmboxpend, osqpend, ostimedly, and ostimedlyhmsm functions. The last two functions are time-related, and other functions are event-related. Therefore, a CPU needs to be executed again, either because the delay is reached, ostimeresume is called, or because the event is triggered. The timer is needed for latency, but the signal does not need a timer.
Therefore, the timer only acts as a delay in the uCOS-II system.

3. How to Improve
According to the function of the timer in the system, you only need to implement the timer delay function. A timer is required to implement latency. Only the frequency of timer interruption triggering can be reduced to improve system performance.
An instant thought-enable when calling the latency function. When the timer is interrupted at the time, the task is switched over and the timer is closed. However, this idea must be improved. When the timer is in the delayed State, another delayed request is triggered. What should I do at this time? I think once I understand this problem, everyone will have the same idea as me-the shortest latency of execution. The remaining tick count of the current timer is compared with the request latency tick count. If the remaining tick count is smaller than the requested tick count, the timer continues after the current timer is completed, to complete the request delay operation.
In the scheduled interrupt, subtract the number of tick that has elapsed for each task, and then perform the next scheduled task.
In actual applications, this latency overlap occurs immediately, and the number of request overlaps is also not fixed. Many people will first think of using a linked list to store the information of each timer. However, the TCB struct contains the remaining tick number members, so they do not have to go any further.
What is the unit of tick? Or 1/OS _ticks_per_sec seconds? If the unit of the Count value in the timer is used, executing an instruction when the tick value is small will change the Count value in the timer, in just a few tick cases, do I need to release the CPU and schedule it to other processes? Scheduled interruptions have been triggered before scheduling is completed. Therefore, the Unit of tick is still 1/OS _ticks_per_sec, so that the program can be compatible with the previous one.
Also, pay attention to the ostimeset and ostimeget functions. The time here is determined based on the global variable ostime, and ostime is updated in ostimetick.

4. Improvement on delayed operations
In the ucosii. h file, modify the OS _tcb structure member variable ostcbdly type and change it to the int16s type.
In OS _core.c, add the mindelaytime initialization statement to the osinit function and modify the ostimetick function as follows:
Int32u mindelaytime = 0;
Void ostimetick (void)
{
# If OS _critical_method = 3
OS _cpu_sr cpu_sr;
# Endif
OS _tcb * ptcb;
Int32u ipassedtime;

Ipassedtime = mindelaytime;
Mindelaytime = 0;
Ostimetickhook ();
# If OS _time_get_set_en> 0
OS _enter_critical ();
Ostime ++;
OS _exit_critical ();
# Endif
Ptcb = ostcblist;
While (ptcb-> ostcbprio! = OS _idle_prio ){
OS _enter_critical ();
If (ptcb-> ostcbdly! = 0 ){
// Subtract the previous scheduled Value
Ptcb-> ostcbdly-= ipassedtime;
If (ptcb-> ostcbdly <= 0 ){
If (ptcb-> ostcbstat & OS _stat_suspend) = 0x00 ){
Osrdygrp | = ptcb-> ostcbbity;
Osrdytbl [ptcb-> ostcby] | = ptcb-> ostcbbitx;
} Else {
Ptcb-> ostcbdly = 1;
}
} Else {
// The latency is not 0.

// Obtain the minimum value of the delay.
If (mindelaytime> ptcb-> ostcbdly)
Mindelaytime = ptcb-> ostcbdly;
}
}
Ptcb = ptcb-> ostcbnext;
OS _exit_critical ();
}

// Delay
If (mindelaytime! = 0)
Hal_starttimer (mindelaytime );
Else
Hal_stoptimer ();
}

OS _time.c is modified as follows:
Extern int32u mindelaytime;
Void ostimedly (int16u ticks)
{
# If OS _critical_method = 3
OS _cpu_sr cpu_sr;
# Endif
Int32u residualticks;

// Obtain the remaining tick count
Residualticks = hal_getresidualticks ();
 
// If the timer is not enabled, enable it and then schedule it.
If (! Hal_istimeon ())
{
Hal_starttimer (ticks );
Ostimedly_old (ticks );
Return;
}
 
// If a timer is enabled,
// Calculate the scheduled time
 
// If the number of request timing times is less than the remaining tick count
If (ticks <residualticks)
{
// Mindelaytime stores the number of tick passed when the scheduled interrupt is triggered.
Mindelaytime-= residualticks-ticks;
Hal_starttimer (ticks );
Ostimedly_old (ticks );
Return;
}
 
// If the timer quantity is greater than the tick quantity, you can directly schedule the timer without restarting it.
Ostimedly_old (ticks );
Return;
}
Change the original ostimedly function to ostimedly_old. Here, ostimedly_old only sets the number of tick task latencies and switches to the next task.
At the same time, in the system initialization function targetinit, remove the timer initialization timer0init (), but keep the initialization of the timer interruption.

5. Test

Sat. What are the advantages and disadvantages of the improved system?
Benefits:
1. The timer interrupt Trigger frequency is reduced.
2.
Disadvantages:
1. ostimeset and ostimeget cannot be used.
2. If a new request delay occurs when a timer is enabled, the original delay will be inaccurate.

 

Code not verified

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.