Ucos ii Task 3: semaphore
What is a semaphore? What is the use of semaphores?
Semaphores can be used to indicate the occurrence of one or more events, and to access shared resources.
Ucos ii provides five functions to operate on semaphores. They are:
1. Create a semaphore, ossemcreate ()
2. Wait for a semaphore, ossempend ()
3. Send a semaphore, ossempost ()
4. Request a semaphore without waiting, ossemaccept ()
5. query the current status of a semaphore, ossemquery ()
The ossemcreate () implementation code is as follows:
OS _event * ossemcreate (int16u CNT) |
{ |
OS _event * pevent; |
|
|
OS _enter_critical (); |
Pevent = oseventfreelist; (1) |
If (oseventfreelist! = (OS _event *) 0) {(2) |
Oseventfreelist = (OS _event *) oseventfreelist-> oseventptr; |
} |
OS _exit_critical (); |
If (pevent! = (OS _event *) 0) {(3) |
Pevent-> oseventtype = OS _event_type_sem; (4) |
Pevent-> oseventcnt = CNT; (5) |
Oseventwaitlistinit (pevent); (6) |
} |
Return (pevent); (7) |
} |
In mc21's view, to create a semaphore, simply apply for an event control block and then initialize the event control block.
First, it obtains an event control block [(1)] From the idle task control block linked list, and adjusts the pointer of the idle Event Control linked list, point it to the next idle Event Control Block [(2)]. If a task control block is available [(3)], set the event type of the task control block to semaphore OS _event_type_sem [(4)]. Other semaphore operation functions ossem ??? () Check this domain to ensure that the task control block type operated is correct. For example, this prevents the ossempost () function from being called to operate a task control block used as a mailbox.
Then, use the initial semaphore value to initialize the task control block [(5)] (if the semaphore is used to indicate the occurrence of one or more events, the initial semaphore value should be set to 0, if the semaphore is used to access shared resources, the initial value of the semaphore should be 1 .), call the oseventwaitlistinit () function to initialize the list of tasks waiting for the event control task control block [(6)]. Because the semaphore is being initialized, No task is waiting for the semaphore.
Finally, ossemcreate () returns a pointer to the task control block to the calling function. All subsequent operations on semaphores, such as ossempend (), ossempost (), ossemaccept (), and ossemquery (), are completed through this pointer. Therefore, this pointer is actually the handle of the semaphore. If no task control block is available in the system, ossemcreate () returns a null pointer.
After creating a signal, you can call ossemquery () to query the status of a signal. This function has two parameters: one is the pointer to the Event Control Block corresponding to the semaphore pevent .; The other is OS _sem_data, a data structure used to record semaphore information.
Simply put, the information of the Event Control Block corresponding to the semaphore is copied to the data structure OS _sem_data.
The ossemquery () program code is as follows:
Int8u ossemquery (OS _event * pevent, OS _sem_data * pdata) |
{ |
Int8u I; |
Int8u * psrc; |
Int8u * pdest; |
|
OS _enter_critical (); |
If (pevent-> oseventtype! = OS _event_type_sem) {(1) |
OS _exit_critical (); |
Return (OS _err_event_type ); |
} |
Pdata-> oseventgrp = pevent-> oseventgrp; (2) |
Psrc = & pevent-> oseventtbl [0]; |
Pdest = & pdata-> oseventtbl [0]; |
For (I = 0; I <OS _event_tbl_size; I ++ ){ |
* Pdest ++ = * psrc ++; |
} |
Pdata-> oscnt = pevent-> oseventcnt; (3) |
OS _exit_critical (); |
Return (OS _no_err ); |
} |