//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //
More original "uC/OS-II Study Notes: Series" Basic and embedded related knowledge details, please visit the cool tiger blog:
Http://blog.csdn.net/dcx1205
I believe it will not disappoint you !!
//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //
UC/OS-II System Development notes
UC/OS-II is a concise and easy-to-use priority-based embedded preemptible multi-task real-time kernel. Although it is very simple, it has indeed greatly liberated my embedded development work. Since it is an operating system kernel, once it is used, it will involve how to design application software based on the operating system.
1. Task framework of uC/OS-II
Void task_xxx (void * parg)
{
/* Initialize the task */
„„
/* Enter the endless loop of the task */
While (1)
{
„„
}
}
Each user's task must comply with the event-driven programming model, that is, the uC/OS-II application must be an event-driven programming model ". A task waits for an event first. An event can be triggered by a system interruption, a task sent by another task, or a time slice waiting by the task itself. When an event occurs, the task is processed accordingly, and then waits for the next event. The cyclic task processing model is "event-driven programming model ".
The event-driven model also covers the interrupt-driven model. uC/OS-II events come from three aspects:
(1) events that interrupt service function sending
(2) caused by system latency
(3) events sent by other tasks.
The "events sent by the interrupted service function" means that when a hardware interruption occurs, the interrupted service program will notify the task in the form of an event, the task with the highest priority of the event will run immediately. The "system delay time caused" event is actually caused by hardware interruption, that is, the system timer is interrupted. The "events sent by other tasks" are determined by the task code itself. This is a complete "soft event ". Regardless of "soft events" or "Hard events", the reason for switching uC/OS-II tasks is "Events ", therefore, when writing application code, you must reflect the "event-driven programming model ".
2. task priority assignment for uC/OS-II
The task priority assignment of uC/OS-II needs to be analyzed according to different system designs. For example, a task with higher real-time requirements has a higher priority.
3. Software hierarchy of uC/OS-II
UC/OS-II will directly manipulate the hardware, such as: the task switching code must save and restore the CPU and co-processor storage; uC/OS-II Kernel Time Base clock requires hardware timer interruption.
BSP is the "board support package", which includes the event-driven model developed based on uC/OS-II, the driver supporting multi-task, these drivers directly control the various hardware modules and use the uC/OS-II system functions for multitasking, they should try to avoid applications directly manipulating the hardware and uC/OS-II kernel. BSP should also provide standard and unified APIs for applications to achieve software levels and reusable application code.
The application is the software that the user develops for the specific application need, it must conform to the uC/OS-II programming model, namely "the event-driven programming model ". Applications should also try to avoid direct control of hardware and direct call of uC/OS-II system functions, variables, a perfect uC/OS-II system does not require applications to be designed for specific hardware. That is to say, uC/OS-II must have a complete device driver, while drivers and BSP provide a complete, standard API.
4, uC/OS-II using mutex signal object should pay attention
Mutual Exclusion semaphore (mutex) is one of the kernel objects of uC/OS-II, used to manage resources that require exclusive access and adapt them to multi-task environments.
To create a mutex, you must specify an idle priority number. The priority of this priority number must be higher than that of all tasks that can use this mutex!
The implementation principle of uC/OS-II mutex is roughly as follows:
When a low-priority task a requests and obtains mutex, it obtains resource access. If Task B of A higher priority starts to run (Task A is denied) and mutex is required, the system will increase the priority of task a to the priority specified by mutex. Because this priority is higher than the priority of any task that may use this mutex, task a immediately obtains CPU control. Until task a releases mutex, task a returns to its original priority level. Then Task B can have the mutex.
Note the following:
After Task A obtains mutex, do not wait for other kernel objects (such as semaphores, mailboxes, queues, and event flags). Instead, try to release mutex as quickly as possible. Otherwise, this mutex will be ineffective, and the effect is worse than simply using semaphores (SEM! Although ordinary semaphores (SEM) can also be used to mutually access an exclusive resource, it may cause a "Priority reversal" problem. Assume that the preceding example uses Sem. After Task A obtains SEM, task C (assuming that task C has a higher priority than task a but is lower than Task B) if you are ready, you will gain CPU control. Therefore, both Task A and Task B will be deprived of CPU control. Task C has a lower priority than Task B, but has a higher priority than Task B! If task a is a task with the lowest priority, it will have the CPU after all the tasks with the highest priority are suspended, then Task B (the highest priority) along with it! This is the priority reversal problem, which violates the "priority-based preemptible real-time multi-task operating system" principle!
To sum up, it is best to use mutex when multiple tasks in the UC/OS-II access exclusive resources, but mutex is relatively CPU time and memory consumption. If a high-priority task needs to use exclusive resources but does not care about waiting for a long time, SEM can be used, because SEM is the most efficient and memory-saving kernel object.
5, uC/OS-II application calls osschedlock () and osschedunlock () functions should note
The osschedlock () and osschedunlock () Functions of the uC/OS-II allow the application to lock the current task and not be preemptible by other tasks. When using osschedlock (), do not call osflagpend (), osmboxpend (), osmutexpend (), osqpend (), ossempend () and other event wait functions! Make sure that the osschedlock () and osschedunlock () functions appear in pairs, especially
In some branch condition statements, consider various branch conditions and do not omit them!
You need to be reminded that when you call the OS _enter_critical () and OS _exit_critical () Functions of the switch interrupt function, make sure that the pair exists. Otherwise, the system may crash! However, osflagpend (), osmboxpend (), osmutexpend (), osqpend (), and ossempend () are called between OS _enter_critical () and OS _exit_critical () functions () such events are allowed by the wait function.
6, uC/OS-II driver programming specifications, particularly recommended
First, we should clarify that we are talking about "drivers" instead of "service interruption", which are often obfuscated by users.
(1) The interrupt service program refers to a short program that will be immediately called by the hardware interrupt controller once a hardware interrupt occurs. Its operation pursuit is simple and clear, and the sooner the service is reduced, the better.
(2) A driver is a function set that encapsulates certain hardware operation details. It provides a unified, standard, clear, and easy-to-use API for applications.
Writing interrupt service programs is often associated with the driver design. For example, if the driver provides the asynchronous operation function, interrupt the service program to prepare a buffer and a struct for it, in addition, the service interruption program automatically performs the required operations according to the member parameters of this struct. For example, the serial port (UART) interrupt service program is designed in two ways: Based on data packet transmission and based on single-byte transmission, the former is applicable to the communication program in the unit of data packets, the latter applies to applications such as super terminals.
If you want to use the same hardware device to complete several different operations in a system, you need to design a universal driver, the driver can install various highly targeted interrupt service programs as needed.
When designing drivers, note that some peripheral operations often take a continuous and strict sequence as atomic operations, for example, use the I/O port to access ds1302, 24c01, and lm75a. During the operation of such devices, other tasks are not allowed to control the corresponding I/O Ports. Otherwise, data errors or device damage may occur. Therefore, drivers of such devices should carefully design "Atomic operations" and encapsulate the time sequence control code that must be operated in a mutex object into an "atomic operation" to adapt to the multi-task environment. In fact, most devices are like this and you need to determine "Atomic operations", such
This is also true for LCD, RTL8019AS, and Flash.
There are still many articles about the driver design, which need to be analyzed in detail. I will not list any items here. I hope you will discuss them more.
Reprinted link:
Http://wenku.baidu.com/view/2ded7952f01dc281e53af03d.html