In the multi-tasking process, the operating system should solve two problems: one is that each task should have a mutual exclusion , that is, for a share of a shared resource , if a task is in use, other tasks can wait until the task releases the resource. Wait for one of the tasks to use it, second, the relevant tasks in order to be executed, a task to wait for its partners to notify or establish a condition to continue to execute, or only wait.
This restrictive cooperative operating mechanism between tasks is called synchronization between tasks .
Events
Communication relies on intermediate media. In uc/os-ii, data structures such as semaphores, Mailboxes ( message Mailboxes ) , and Message Queuing are used as intermediate media. Because these data structures will affect the program flow of tasks, they are also referred to as events .
The operation to send information to an event is called a send event , and the operation to read the event is called a request event , or a wait event .
Signal Volume
semaphores are a class of basic events used to communicate between tasks. Because a binary event can achieve exclusive occupancy of a shared resource, it is called a mutex semaphore . The signal count is called the semaphore.
Set a wait time limit for the task waiting for semaphores. If the task waiting for the semaphore has not waited for this signal because the wait time has elapsed, then the task is left out of the waiting state to continue running, so there will be no freezing phenomenon.
In a stripped-down kernel that is strictly prioritized for scheduling, the priority level determines whether the task obtains the processor's right to use, and whether the semaphore can be obtained determines whether it can be run. In other words, in a task that uses semaphores to synchronize, there are two conditions that constrain the task's ability to run : one is its priority , and the other is whether it obtains the semaphore it is waiting for. It is this fact that has produced a priority reversal problem that has to be solved, and it is this fact that makes the C/s structure of the operating system possible.
Message Mailbox
in a multitasking operating system, it is often necessary to communicate between tasks by passing a data called a message. For this purpose, you can create a storage space in memory as a buffer for that data. If this buffer is called a message buffer, one of the simplest ways to pass data (messages) between tasks is to pass the message buffer. Thus, the data structure (event) used to pass the message buffer pointer is called the message mailbox.
Message Queuing
The above message mailbox can be used not only to pass a message, but also to define an array of pointers. Having each element of the array hold a message buffer pointer, the task can pass multiple messages by passing the pointer array pointer. This data structure that can pass multiple messages is called Message Queuing.
List of waiting tasks for events
as a well-functioning event, you should have two management functions for these wait tasks: one is to record and sort all the tasks waiting for the event, and the other is to allow the task to have a certain waiting time limit .
for logging and sorting of waiting event tasks, Uc/os-ii uses a method similar to the task-ready table to define an array of type int8u oseventtbl[] As the record table for the record waiting event task, this table is called the waiting task table. A int8u variable oseventgrp is also defined to represent the task group waiting in the task table.
As for the waiting time limit for a task, it is recorded in the member ostcbdly of the task control block TCB that waits for the task, and is maintained in each clock beat Interrupt service program. Whenever the waiting time limit for a task has arrived, the task is removed from the event waiting task table and put into a ready state.
Event control block
Uc/os-ii combines the event waiting task table with other information related to the event to define a data structure called the event control block ECB . In this way, the ECB is used uniformly in uc/os-ii to describe the events of injected semaphores, mailboxes (message mailboxes), and message queues.
in uc/os-ii. H , press the control block as defined below:
#if (os_max_events >= 2)
typedef struct {
void *oseventptr; /* Pointer to message or queue structure * /
int8u oseventtbl[os_event_tbl_size]; */List of tasks waiting for EVENT to occur * /
int16u oseventcnt; /* Count of used when event is a semaphore * /
int8u Oseventtype; /* Os_event_type_mbox, os_event_type_q or Os_event_type_sem * /
int8u oseventgrp; /* Group corresponding to tasks waiting for event to occur * /
} os_event;
#endif
Member Oseventtbl[os_event_tbl_size] is an array that is the same as the format of the task-ready table. All tasks in the application occupy a bits in the table by priority, and the value of the bit is either 1 or zero to indicate whether the corresponding task is a task waiting for the event, which is called the task waiting table.
Basic function Operations for event control blocks
Uc/os-ii has 4 functions that perform basic operations on the event control block (defined in file os_core. C ), called by functions that manipulate semaphores, message mailboxes, message queues, and so on.
1) initialization functions for event control blocks
#if (os_q_en && (Os_max_qs >= 2)) | | Os_mbox_en | | Os_sem_en
void Oseventwaitlistinit (os_event *pevent)// pointer to the event control block
The function is called by the os***create () function when the task calls the Os***create () function to create an event. Here * * * Representative :Sem,Mutex,Mbox,Q.
2) a function that causes a task to enter a wait state
Place a task in a wait state to invoke the oseventtaskwait() function .
#if (os_q_en && (Os_max_qs >= 2)) | | Os_mbox_en | | Os_sem_en
void oseventtaskwait (os_event *pevent)
The function will be called by Os***pend () when the task calls the function os***pend () to request an event.
3) a function that is waiting for a task to enter a ready state
Call the function Oseventtaskrdy(), the task calling this function in the task waiting table in the position of 0 (de-wait), then the task in the Task Ready table in the corresponding position 1, and then raise a task scheduling.
#if (os_q_en && (Os_max_qs >= 2)) | | Os_mbox_en | | Os_sem_en
void Oseventtaskrdy (Os_event *pevent, void *msg, int8u MSK)
The function will be called by the function os***post () when it sends an event when the task calls the function Os***post ().
4) a function that causes a wait-time-out task to enter a ready state
Call the function Oseventto ()If a task that is waiting for an event has already exceeded the waiting time, but still has a condition that can be run due to a gain event and so on, but also to get it into a ready state.
#if (os_q_en && (Os_max_qs >= 2)) | | Os_mbox_en | | Os_sem_en
void Oseventto (os_event *pevent)
The function is called by Os***pend () when the task calls Os***pend () to request an event.
Empty event control block linked list
similar to the method of managing task control blocks, UC/OS-II organizes event control blocks into two linked lists for management.
When Uc/os-ii is initialized, the system will follow the total number of events used by the application in the initialization function Osinit () os_max_events (os_cfg. H), create a os_max_events empty event block, and borrow member oseventptr as a link pointer to form a one-way list.