UC/OS-II Application Basic Structure

Source: Internet
Author: User
Tags manual require cpu usage

 UC/OS-II Application Infrastructure
To apply UC/OS-II, naturally to develop applications for it, the following discusses the basic structure of UC/OS-II-based applications and considerations.
Each Uc/os-ii app must have at least one task. And each task must be written in the form of an infinite loop. The following is the recommended structure:

void task  ( void* pdata )

{

Int8u err;

Inittimer (); //  optional

for ( ;;  )

{

//  your application code

...

.....
.
ostimedly (1); //  optional

}

}
Why write in the form of an infinite loop? That's because the system keeps a stack space for each task, and the system changes the recovery context when the task is switched, and executes a reti  instruction return. If you allow a task to execute to the last curly brace (which generally means a RET directive), it is likely to break the system stack space and make the application's execution indeterminate. In other words, it's "run-fly". Therefore, each task must be written in the form of an infinite loop. Programmers must believe that their task is to abandon the use of the CPU, whether the system is forced (through the ISR) or unsolicited (by calling Os api).  

Now to talk about the Inittimer () function in the above program, this function should be provided by the system, and the programmer is obliged to call it within the highest priority task and not within the for loop. Note that this function is related to the CPU used, and each system has its own timer initialization program. In Uc/os-ii's Help manual, the author emphasizes that it is absolutely impossible to invoke the timer initializer within osinit () or Osstart (), which can damage the portability of the system and result in a performance penalty. So, a compromise approach is to call it in the highest priority program, like above, to ensure that when Osstart () calls the system intrinsic function Osstarthighrdy () Start multitasking, the first thing to do is the timer initialization program. or a special priority task, only one thing, that is to perform a timer initialization, and then by calling Ostasksuspend () to hang up, and never execute again. But that would waste a TCB space. For those systems with tight ram, it's still not a good thing.

(iii) Introduction of some important UC/OS-II APIs



Any operating system will provide a large number of APIs for programmers to use, UC/OS-II is no exception. Because uc/os-ii is oriented to embedded development and does not require chatty, the API provided by the kernel is mostly related to multitasking. The main categories are as follows:

1) Task class

2) Message Class

3) Synchronization Class

4) Time Class

5) critical section and event class

I personally think that for the novice programmer, the task class and the time class are the two types of APIs that must be mastered first. Here I will introduce the more important:

1) ostaskcreate function
This function should be called at least once within the main function, after the Osinit function call. The role is to create a task. There are currently four parameters, namely the entry address of the task, the parameters of the task, the first address of the task stack, and the priority of the task. When this function is called, the system first requests an empty TCB pointer from the TCB idle list, and then initializes the task stack based on the user-given parameters and marks the task as ready within the internal task-ready table. Finally, this task is created successfully.

2) Ostasksuspend function

This function is very simple, the name should understand its role, it can suspend the specified task. If the current task is suspended, it will also cause the system to perform a task switch pilot function osshed to perform a task switch. This function has only one parameter, which is the priority of the specified task. Then why is it a priority? In fact, in the system, the priority in addition to the order of the execution of a task, but also play the role of each task, in other words, the priority is the ID of the task. Therefore, Uc/os-ii does not allow tasks of the same priority to occur.

3) Ostaskresume function



This function, in contrast to the above function, is used to restore the specified suspended function to the ready state. If the restore task has a higher priority than the current task, a task switch is also raised. Its parameters are similar to the Ostasksuspend function, which specifies the priority of the task. It is necessary to note that this function does not require the use of ostasksuspend functions in pairs.

4) Os_enter_critical macro



A lot of people think it is a function, but in fact, careful analysis of OS_CPU. h file, it and the os_exit_critical to be talked about right away are all macros. They are all implementations that involve a particular CPU. are generally replaced by one or more embedded assembly codes. Since the system wants to hide the internal implementation from the upper-level programmer, it is generally declared that the system enters the critical section after executing this instruction. In fact, it's just a break down. In this way, as long as the task does not actively abandon the CPU access, the other tasks will not occupy the CPU opportunity, relative to this task, it is exclusive. So I went into the critical section. This macro can be used less or less because it destroys some of the system's services, especially the time service. And the system to the external response performance is reduced.

5) Os_exit_critical macro



This is with the macro described above to use another macro, which is described in the System manual is to exit the critical section. In fact, it is a re-open interrupt. It is important to note that it must be paired with the macro above, or it will have unintended consequences. In the worst case, the system crashes. We recommend that programmers use as few of these macro calls as possible, because they do disrupt the system's multitasking performance.

6)ostimedlyFunction



This should be the most programmers call a function, the function is very simple, it is to suspend the current task, then the task to switch, after the specified time, the current task to return to the ready state, but does not necessarily run, if the recovery is the highest-priority-ready task, then run. Simply put, it is possible to delay the task after a certain time to execute it, or, temporarily abandon the use of the CPU. A task can not explicitly invoke these APIs, which can lead to the abandonment of CPU usage, but the performance of multitasking will be greatly reduced, because the clock mechanism is the only time to switch tasks. A good task should be in the completion of some operations to actively abandon the right to use, good things to share.

(iv) Analysis of UC/OS-II Multi-task realization mechanism
As already mentioned, Uc/os-ii is a preemptive multi-tasking kernel based on priority. So how does the multitasking mechanism work? Understanding these principles can help us write more robust code. Because we are facing the novice programmer, this article does not intend to write another uc/os-ii of the source code analysis, the article is too many, this article intends to discuss this issue from the perspective of the principle of implementation.

First, let's see why the multi-tasking mechanism can be implemented. In fact, in the case of a single CPU, there is no real multi-tasking mechanism, there are only different tasks in turn using the CPU, it is essentially a single task. But because the CPU is executing very fast, plus the task switching is very frequent and switching quickly, we feel as if there are many tasks running at the same time. This is called a multi-tasking mechanism.

From the above description, it is not difficult to find that to achieve a multi-tasking mechanism, then the target CPU must have a way to change the PC at run time, or can not be switched. Unfortunately, the direct setting of the PC pointer does not currently have any CPU support for such instructions. But the general CPU is allowed to modify the PC indirectly through instructions like Jmp,call. The realization of our multi-tasking mechanism is based on this point of departure. In fact, we use the call command or the soft interrupt instruction to modify the PC, mainly soft interrupts. On some CPUs, however, there is no concept of soft interrupts, so we use a few push instructions on those CPUs and a call command to simulate the occurrence of a soft interrupt.

Recall the knowledge you learned in the microcomputer principle course, when an interrupt occurs, the CPU saves the value of the current PC and status register into the stack, then sets the PC as the entry address of the interrupt service program, and then a machine cycle to execute the Interrupt service program. After execution, it is common to execute a RETI instruction that restores the values in the current stack to the status register and to the PC. In this way, the system will go back to where it was before the outage was executed. So imagine. What happens if the value in the stack is changed artificially when you break it again. Or what happens by changing the value of the current stack pointer. If the change is arbitrary, then the result is an unpredictable error. Because we can't determine what instructions the machine will execute next, but if the change is planned, then we can implement a multitasking mechanism if the changes are in accordance with certain rules. In fact, this is the core part of almost all of the current OS. But their implementation is not as simple as this.

Next, let's see how uc/os-ii is dealing with this. In Uc/os-ii, each task has a task control block, which is a more complex data structure. Where the task control is fast-shifted to 0, a pointer is stored that records the private stack address of the owning task. In fact, in the UC/OS-II, each task has its own dedicated stack, which cannot be violated. This requires programmers to be assured in their programs. The general practice is to declare them as static arrays. And be declared as OS_STK type. When the task has its own stack, then it is possible to record each task stack there in the previous task control where the fast offset is 0. In the future, whenever a task switch occurs, the system must first enter an interrupt, which is usually achieved by a soft interrupt or a clock interrupt. The system then saves the stack address of the current task and then resumes the stack address of the task to be switched. Because of which task's stack must also have the address (remember what we said earlier, whenever a task switch occurs, the system will inevitably enter an interrupt, and once the interrupt CPU will put the address into the stack), so that the changes to the PC for the next task address.

The above is the multi-tasking implementation mechanism of UC/OS-II, we are here to talk about this issue, it is hoped that our handlers can use this mechanism to write more robust, more efficient code.


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.