120 likes | 254 Views
Synchronization. Akos Ledeczi EECE 354, Fall 2012 Vanderbilt University. Semaphores. They work for synchronization too ISR to Task or Task to Task. Unilateral Rendezvous. Task calling Pend() does not need to know about the details: the Pend() call will return when the event has occurred
E N D
Synchronization Akos Ledeczi EECE 354, Fall 2012 Vanderbilt University
Semaphores • They work for synchronization too • ISR to Task or • Task to Task
Unilateral Rendezvous • Task calling Pend() does not need to know about the details: the Pend() call will return when the event has occurred • Maximizes use of CPU; no busy waiting • Event (i.e., Post()) will cause the waiting task to run immediately (assuming it has the highest priority)
Credit Tracking • Semaphore accumulates the number of times Post() has been called /without a corresponding Pend()/
Broadcasting • Multiple tasks waiting on a semaphore • OS_OPT_POST_ALL • All waiting tasks become ready to run • Care must be taken because some of the tasks may not have called Pend() yet
Task Semaphores • In µC/OS-III each task has a built-in semaphore • More efficient • OSTaskSemPend(); OSTaskSemPost(); etc. • Post()-er (ISR or Task) needs to know which task to notify
Bilateral Rendezvous void Task1(void *p_arg) { … OSTaskSemPost(&Task2_TCB, OS_OPT_POST_1, &err); OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,&ts,&err); … } void Task2(void *p_arg) { … OSTaskSemPost(&Task1_TCB, OS_OPT_POST_1, &err); OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,&ts,&err); … } • Only between tasks, as an ISR cannot Pend()
Event Flags • When tasks need to synchronize on multiple events • When any of the events is enough: disjunctive synchronization (OR) • When all events are needed: conjunctive synchronization (AND) • OSFlag???(); • OSFlagPendGetFlagsRdy(): which flags caused task to become ready
EventFlags Example #define TEMP_LOW (OS_FLAGS)0x01 #define BATT_LOW (OS_FLASG)0x02 #define SW_PRESSED (OS_FLAGS)0x04 OS_FLAG_GRP MyEventFlagGrp; void main() { … OSFlagCreate(&MyEventFlagGrp, “My flags”,0,&err); … } void Task1(void *p_arg) { … for( ; ; ) { OSFlagPend(&MyEventFlagGrp, TEMP_LOW + BATT_LOW, 0 OS_OPT_PEND_FLAG_SET_ANY, ts,&err); … } } void Task2(void *p_arg) { … for ( ; ; ) { OSFlagPost(&MyEventFlagGrp, BATT_LOW, OS_OPT_POST_FLAG_SET, &err); } … }
Status and Transient Events • Typically: • Status info monitored by one task, handled by another task using a non-blocking call • A transient event is generated by an ISR or task and handled and consumed by a task using a blocking call
Event Flag Internals structos_flag_grp { OS_OBJ_TYPE Type CPU_CHAR *NamePtr OS_PEND_LIST PendList; OS_FLAGS Flags CPU_TS TS }; OSFlagPost(&flagGrp, (OS_FLAGS)0x0C, OS_OPT_FLAG_SET, &err); • Pend list is not in priority order as all tasks need to be looked at anyways • Look at code on the left: • If OS_OPT_FLAG_SET and flags contain 0x03, result will be 0x0F • IfOS_OPT_FLAG_CLR and flags contain 0x0F, result will be 0x03