Ucos Real-time operating system of inter-mission communication there are many kinds, I mainly study the SEM, mutex, queue, messagebox these four kinds. System kernel code, these kinds of tasks between the implementation mechanism of the communication mechanism is similar, next record my knowledge of the core code, for later back to see, but it is regrettable that did not carefully learn the extension code of the functional implementation part. The kernel code implementation of the Ucos operating system is relatively straightforward, but it is useful for understanding the same functionality as other operating system cores.
Ucos communication mechanism is mainly based on the event implementation, in fact, understand that this event does not translate into Chinese events, it is called the event feeling is more easily received. The following is the data structure of the operating system event:
typedefstructos_event {int8u oseventtype; /*Type of event control block (see OS_EVENT_TYPE_XXXX)*/ void*oseventptr;/*Pointer to message or queue structure*/int16u oseventcnt; /*Semaphore Count (not used if other EVENT type)*/Os_prio oseventgrp; /*Group corresponding to tasks waiting for event to occur*/Os_prio Oseventtbl[os_event_tbl_size]; /*List of tasks waiting for event to occur*/} os_event;
The above event is to implement the SEM, mutex, queue, MessageBox and other essential structure, in fact, the structure is relatively simple, mainly including oseventtype used to record the current event is the previous four mechanisms of which Oseventptr is a pointer to the address of the MessageBox and queue to be passed; oseventcnt is a count value for SEM, and for a mutex it is a variable that records task precedence. , OSEVENTGRP and OSEVENTTBL are similar to the OSRDYGRP and Osrdytbl mentioned earlier, and the main records are what tasks are waiting for the current event. For the above four kinds of mechanism implementation, first need to create an event in order to achieve their own functions, such as ossemcreate,osmutexcreate.
The main function of Ucos's SEM is a limitation on the use of resources, when the value of the semaphore is set to N to allow n tasks to be used for the current resource, and if the resource is occupied by n tasks, the n+1 task needs to wait for 1 or more of the previous N tasks to release the use of the resource. The specific function of SEM is ossemcreate,ossempend,ossempost, such as the three functions, the following will be a detailed analysis of these three functions.
For SEM, the first need to create an event structure, and then set this SEM event allows several tasks can be used at the same time, the specific function ossemcreate first:
Os_event *ossemcreate (int16u cnt) {os_event*pevent; if(Osintnesting >0u) {/*See if called from ISR ...*/ return((Os_event *)0);/*... can ' t ' CREATE from an ISR*/} os_enter_critical (); Pevent=oseventfreelist;/*Get Next free event control block*/ if(Oseventfreelist! = (Os_event *)0) {/*See if pool of free ECB pool is empty*/oseventfreelist= (Os_event *) oseventfreelist->oseventptr; } os_exit_critical (); if(Pevent! = (Os_event *)0) {/*Get an event control block*/pevent->oseventtype =Os_event_type_sem; Pevent->oseventcnt = CNT;/*Set Semaphore Value*/pevent->oseventptr = (void*)0;/*Unlink from the ECB free list*/Os_eventwaitlistinit (pevent); /*Initialize to ' Nobody waiting ' on SEM. */ } return(pevent);}
The four inter-mission communication mechanisms mentioned above are not allowed to be created in interrupts, so ossemcreate first determines whether the current creation process is in the interrupt, that is, if the osintnesting is greater than 0, There is a global variable oseventfreelist records the current operating system how many free event in the list, ossemcreate from the free list to take an event agency, Then oseventfreelist points to the next unused event, and then sets Oseventtype and oseventfreelistcnt,cnt as parameters that are brought in with the CREATE function, which is set by the programmer who uses the function. SEM does not use the OSEVENTPTR variable because it is a pointer, so it is set to 0, then the Event Group and event table of the event is initialized, indicating that there is currently no task waiting to be created by the SEM, returning the address of the event structure, Pend and post are used for later speaking.
Secondly, it is necessary to refer to the SEM mechanism post and pend two operations, the two operations are paired, the simple point of pend main function is to check the Create event in the OSEVENTCNT is greater than 0, if greater than 0, indicating the resources to be protected also allows the task to use, This time only need to oseventcnt minus 1 operation, indicating that another task occupies the right to use the resources; if oseventcnt is not greater than 0, then the permissions on the resources that the task can use have reached the upper limit, and the task of the resource to be used will be suspended (1) to wait. and put the task into the Event Group and event table of the event, the waiting task can only continue to run until other tasks release the use of the resource. The main function of post is to release the use of the occupied resources, its operation will first check the current event of the Group and table is not waiting for the current event of the task exists, if there is a right to use direct to wait for the task (1), do not need to oseventcnt plus operation, If you do not have a task waiting for the current event, you only need to add the OSEVENTCNT plus 1 operation, indicating that the resource can be used with a larger one. Let's take a look at specific pend and post code-specific procedures.
voidOssempend (Os_event *pevent, int32u timeout, int8u*Perr) { if(Pevent->oseventtype! = Os_event_type_sem) {/*Validate Event block type*/*perr =Os_err_event_type; return; } if(Osintnesting >0u) {/*See if called from ISR ...*/*perr = OS_ERR_PEND_ISR;/*... can ' t PEND from an ISR*/ return; }os_enter_critical (); if(Pevent->oseventcnt >0u) {/*If SEM. is positive, resource available ...*/pevent->oseventcnt--;/*... decrement semaphore only if positive. */os_exit_critical (); *perr =Os_err_none; return; } /*Otherwise, must wait until event occurs*/Ostcbcur->ostcbstat |= Os_stat_sem;/*Resource not available, pend on Semaphore*/Ostcbcur->ostcbstatpend =OS_STAT_PEND_OK; Ostcbcur->ostcbdly = timeout;/*Store pend timeout in TCB*/os_eventtaskwait (pevent); /*Suspend task until event or timeout occurs*/os_exit_critical (); os_sched (); /*Find Next highest priority task ready*/os_enter_critical (); Switch(Ostcbcur->ostcbstatpend) {/*See if we timed-out or aborted*/ CaseOS_STAT_PEND_OK:*perr =Os_err_none; Break; CaseOs_stat_pend_abort:*perr = Os_err_pend_abort;/*indicate that we aborted*/ Break; Caseos_stat_pend_to:default: Os_eventtaskremove (Ostcbcur, pevent); *perr = Os_err_timeout;/*indicate that we didn ' t get the event within to*/ Break; } ostcbcur->ostcbstat = Os_stat_rdy;/*Set task status to Ready*/Ostcbcur->ostcbstatpend = OS_STAT_PEND_OK;/*Clear pend Status*/Ostcbcur->ostcbeventptr = (Os_event *)0;/*Clear Event Pointers*/os_exit_critical ();}
The Ossempend function first determines whether the current task operation is a SEM event, then determines whether the interrupt, if yes, returns an error, and then checks if the value of the resource limit for the SEM event is greater than 0, and if so, the decrement indicates that the semaphore is occupied by a task, if not greater than 0, Description for the Change event, there is no semaphore available to use the required operation is to suspend the current task, and invoke the task switch function, in the above code in os_sched () above the four-step operation is to suspend the task operation, until there is a semaphore can be used to perform the task switch again, Will switch to the current task to continue execution from os_sched, you can see that the following action is to remove the task from the waiting Group and table of the event, and change the task's status to Os_stat_rdy. Of course, the task is also statpend state, here do not do a detailed introduction.
int8u Ossempost (Os_event *pevent) { if(Pevent->oseventtype! = Os_event_type_sem) {/*Validate Event block type*/ return(Os_err_event_type); } os_enter_critical (); if(Pevent->oseventgrp! =0u) {/*See if the task waiting for Semaphore*/ /*Ready HPT Waiting on event*/ (void)Os_eventtaskrdy(Pevent, (void*)0, Os_stat_sem, OS_STAT_PEND_OK); Os_exit_critical (); Os_sched (); /*Find HPT ready to run*/ return(Os_err_none); } if(Pevent->oseventcnt <65535u) {/*Make sure Semaphore would not overflow*/pevent->oseventcnt++;/*Increment semaphore count to register event*/os_exit_critical (); return(Os_err_none); } os_exit_critical (); /*Semaphore value have reached its maximum*/ return(OS_ERR_SEM_OVF);}
Ossempost function implementation is relatively simple, after judging whether the current operation is the SEM event, the current event to determine whether to wait for the event in the group has a task, If there is a task that is set to wait for the event to have that semaphore set to change the task in Rdy state and then perform task scheduling, so that the waiting task can be executed, here is a clever design is for the semaphore measurement value oseventcnt do not operate, Because if the event waits for a wait task in the group, it means that the semaphore is released here, waiting for the task to get the semaphore. If there is no waiting task in the group, the oseventcnt is added, indicating that a task has released the semaphore. The main function of this function in Os_eventtaskrdy is to parse the event's waiting group and table tasks into the task Rdy list and remove the waiting task from the list in the event.
If the semaphore value is set to 1, it is a special case, that is, only 1 tasks have semaphores, a bit mutually exclusive means, but unlike the mutex, the mutex in order to prevent low priority to occupy the resources, but because the low priority is not executed, and high priority is not the low priority of the resources occupied by the resource and cannot be executed, The precedence inheritance mechanism is used . The kernel implementation of the Ucos mutex is then introduced.
Ucos Real-time Operating system learning notes-inter-mission communication (semaphore)