UC/OS-II Application Infrastructure

Source: Internet
Author: User
Tags manual require

The

 UC/OS-II application Infrastructure
applies uc/os-ii, and it is natural to develop applications for it, following the basic architecture and considerations for UC/OS-II based applications.
Each UC/OS-II application must have at least one task. And each task must be written in the form of infinite loops. The following structure is recommended:

void task  ( void* pdata )

{

Int8u err;

Inittimer (); //  optional

for  ;;  )

{

//  your application code

... ...

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

}

}
Why write an infinite loop? That's because the system keeps a stack space for each task, the system changes the recovery context when the task switches, and executes a reti  instruction return. If a task is allowed to execute to the last curly brace (which generally means a ret instruction), it is likely to break the system stack space and make the application's execution uncertain. In other words, it's "Run Away". Therefore, each task must be written in the form of infinite loops. Programmers must believe that their task is to relinquish the right to use the CPU, whether the system forces (through ISR) or unsolicited (by calling Os api).  

Now to talk about the Inittimer () function in the above program, which should be provided by the system, the programmer is obligated to call it within the highest priority task and cannot be invoked within the for loop. Note that this function is related to the CPU being used, and each system has its own timer initialization program. In the UC/OS-II help manual, the authors specifically emphasize that it is absolutely impossible to invoke the timer initializer in osinit () or Osstart (), which can damage the system's portability and result in performance losses. So, a compromise approach is to call it in the highest priority program, as above, to ensure that when Osstart () calls the system's internal function Osstarthighrdy () starts multitasking, the first thing to do is the timer initialization program. or a special priority task, only do one thing, that is, execute timer initialization, and then by calling Ostasksuspend () to hang yourself, never to execute again. But this will waste a TCB space. For those systems that have a tight ram, it's not good.

(iii) Introduction to 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. Since uc/os-ii is oriented to embedded development and does not require all-inclusive, the APIs provided by the kernel are 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 beginners, task classes and time classes 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 in 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 free list, and then initializes the task stack based on the user's given parameters and marks the task as ready in the internal task-ready table. Finally returned, such a task was created successfully.

2) Ostasksuspend function

This function is very simple, the first look at the name should understand its role, it can suspend the specified task. If the suspension is the current task, it will also cause the system to perform a task to switch the pilot function osshed to make a task switch. This function has only one argument, and that is the priority of the specified task. So why is it a priority? In fact, within the system, the priority, in addition to the order in which a task is executed, also plays the role of each task, in other words, the priority is the ID of the task. Therefore, UC/OS-II does not allow the same priority tasks to occur.

3) Ostaskresume function



This function, contrary to the function above, is used to restore the specified suspended function to a ready state. If the recovery task takes precedence over the current task, it also initiates a task switch. The parameter is similar to the Ostasksuspend function, which is the priority of the specified task. It is necessary to note that this function does not require the use of ostasksuspend functions.

4) Os_enter_critical macros



A lot of people think it is a function, but it is not, carefully analyze the os_cpu. h file, it and the following immediately to talk about the os_exit_critical are macros. They are all involved in the implementation of a particular CPU. are generally replaced by one or more embedded assembly code. Because the system wants to hide internal implementations from the top programmer, it is generally claimed that the system enters the critical section after executing this instruction. Actually, it's just an interruption. In this way, as long as the task does not voluntarily discard CPU access, other tasks will not occupy CPU opportunity, relative to this task, it is exclusive. So it goes 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 make the system to the external response performance reduced.

5) Os_exit_critical Macros



This is another macro that is used with the macros described above, which is described in the System manual as exiting the critical section. In fact, it is to reopen the interruption. It is important to note that it must be aligned with the above macro, otherwise it will have unintended consequences. In the worst case, the system crashes. We recommend programmers to use these two macro calls as little as possible, because they do destroy the system's multitasking performance.

6)ostimedlyFunction



This should be a function that programmers call the most. This function is very simple to complete the function is to suspend when the current task, and then the task switch, at the specified time after the arrival of the current task back to the ready state, but does not necessarily run, if the recovery is the highest priority for the task, then run. In simple terms, it is possible to delay the task after a certain period of time to execute it, or, temporarily give up the right to use the CPU. A task can not explicitly invoke these APIs that can lead to the abandonment of the CPU, but that multitasking performance can be significantly reduced because of the clock mechanism in which task switching occurs. A good task should be done in the completion of a number of initiatives to give up the right to use, good things to share it.

(iv) Analysis of UC/OS-II Multi-task implementation mechanism
As has been said before, Uc/os-ii is a preemptive multitasking kernel based on priority. So how does the multitasking mechanism actually 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 source analysis, so many articles, this article intends to from the point of view of the realization of the principle to explore this issue.

First, let's see why multitasking can be done. In fact, in the case of a single CPU, there is no real multitasking mechanism, there are only different tasks in turn using the CPU, so essentially a single task. But because the CPU executes very quickly, plus the task switching is very frequent and the switch is very fast, so we feel like a lot of tasks are running at the same time. This is called a multitasking mechanism.

From the above description, it is not difficult to find, to implement the multitasking mechanism, then the target CPU must have a way to change the PC in the runtime, otherwise it will not be able to switch. Unfortunately, the direct setting of the PC pointer, there is no CPU to support such instructions. But the general CPU allows the PC to be modified indirectly through instructions like Jmp,call. The implementation of our multitasking mechanism is also based on this starting point. In fact, we use call instructions or soft interrupt instructions to modify the PC, mainly soft interrupts. But on some CPUs, there is no such thing as soft interrupts, so we use several push instructions and a call instruction on those CPUs to simulate the occurrence of a soft interrupt.

Think back to the knowledge that you have learned in the course of microcomputer principle, when the interruption occurs, the CPU saves the value of the current PC and status register to the stack, then sets the PC as the entry address of the interrupt service program, and then goes down a machine cycle to execute the Interrupt service program. After execution, a reti instruction is generally executed, which pops up the value in the current stack back to the status register and PC. In this way, the system goes back to where it was before the interruption. So imagine. If you interrupt again, artificially change the value in the stack, what happens. Or what happens if you change the value of the current stack pointer. If the change is arbitrary, the result is an unpredictable error. Because we're not sure what the next command is going to be, but if the change is planned, we can implement a multitasking mechanism if we follow certain rules. In fact, this is the core of almost all the OS at the moment. But their implementation is not as simple as this.

Next, let's look at how the UC/OS-II is handled in this respect. In Uc/os-ii, each task has a task control block, which is a more complex data structure. Where task control is fast offset to 0, a pointer is stored that records the dedicated stack address of the task to which it belongs. In fact, in 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 a task has its own stack, it is possible to record each task stack again where the task control is fast offset to 0. In the future, whenever a task switch occurs, the system will inevitably enter a break, which is usually done through a soft interrupt or a clock interrupt. The system then saves the stack address of the current task before resuming the stack address of the task to be switched. Because there must be an address in the stack of which task (remember what we said earlier, every time a task switch occurs, the system is bound to enter an interrupt, and once the CPU is interrupted, the address is pressed onto the stack, thus achieving the purpose of modifying the PC's address for the next task.

The above is the UC/OS-II implementation mechanism, we are here to talk about this problem, is the hope that our program members can use this mechanism, 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.