<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>

您好,歡迎來電子發燒友網! ,新用戶?[免費注冊]

您的位置:電子發燒友網>源碼下載>uCOS編程>

uCOS-II-V280是當前UCosII最新版本源代碼

大?。?/span>918 人氣: 2010-02-24 需要積分:0
的空間

用戶級別:注冊會員

貢獻文章:

貢獻資料:

uCOS-II-V280是當前UCosII最新版本源代碼

/*
*********************************************************************************************************
*??????????????????????????????????????????????? uC/OS-II
*????????????????????????????????????????? The Real-Time Kernel
*????????????????????????????????????????? SEMAPHORE MANAGEMENT
*
*????????????????????????? (c) Copyright 1992-2005, Jean J. Labrosse, Weston, FL
*?????????????????????????????????????????? All Rights Reserved
*
* File??? : OS_SEM.C
* By????? : Jean J. Labrosse
* Version : V2.80
*********************************************************************************************************
*/

#ifndef? OS_MASTER_FILE
#include
#endif

#if OS_SEM_EN > 0
/*
*********************************************************************************************************
*?????????????????????????????????????????? ACCEPT SEMAPHORE
*
* Description: This function checks the semaphore to see if a resource is available or, if an event
*????????????? occurred.? Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the
*????????????? resource is not available or the event did not occur.
*
* Arguments? : pevent???? is a pointer to the event control block
*
* Returns??? : >? 0?????? if the resource is available or the event did not occur the semaphore is
*???????????????????????? decremented to obtain the resource.
*????????????? == 0?????? if the resource is not available or the event did not occur or,
*???????????????????????? if 'pevent' is a NULL pointer or,
*???????????????????????? if you didn't pass a pointer to a semaphore
*********************************************************************************************************
*/

#if OS_SEM_ACCEPT_EN > 0
INT16U? OSSemAccept (OS_EVENT *pevent)
{
??? INT16U???? cnt;
#if OS_CRITICAL_METHOD == 3?????????????????????????? /* Allocate storage for CPU status register????? */
??? OS_CPU_SR? cpu_sr = 0;
#endif

#if OS_ARG_CHK_EN > 0
??? if (pevent == (OS_EVENT *)0) {??????????????????? /* Validate 'pevent'???????????????????????????? */
??????? return (0);
??? }
#endif
??? if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {?? /* Validate event block type???????????????????? */
??????? return (0);
??? }
??? OS_ENTER_CRITICAL();
??? cnt = pevent->OSEventCnt;
??? if (cnt > 0) {??????????????????????????????????? /* See if resource is available????????????????? */
??????? pevent->OSEventCnt--;???????????????????????? /* Yes, decrement semaphore and notify caller??? */
??? }
??? OS_EXIT_CRITICAL();
??? return (cnt);???????????????????????????????????? /* Return semaphore count??????????????????????? */
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*?????????????????????????????????????????? CREATE A SEMAPHORE
*
* Description: This function creates a semaphore.
*
* Arguments? : cnt?????????? is the initial value for the semaphore.? If the value is 0, no resource is
*??????????????????????????? available (or no event has occurred).? You initialize the semaphore to a
*??????????????????????????? non-zero value to specify how many resources are available (e.g. if you have
*??????????????????????????? 10 resources, you would initialize the semaphore to 10).
*
* Returns??? : != (void *)0? is a pointer to the event control clock (OS_EVENT) associated with the
*??????????????????????????? created semaphore
*????????????? == (void *)0? if no event control blocks were available
*********************************************************************************************************
*/

OS_EVENT? *OSSemCreate (INT16U cnt)
{
??? OS_EVENT? *pevent;
#if OS_CRITICAL_METHOD == 3??????????????????????????????? /* Allocate storage for CPU status register */
??? OS_CPU_SR? cpu_sr = 0;
#endif

??? if (OSIntNesting > 0) {??????????????????????????????? /* 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 was 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 ECB free list??????????????? */
#if OS_EVENT_NAME_SIZE > 1
??????? pevent->OSEventName[0] = '?';????????????????????? /* Unknown name???????????????????????????? */
??????? pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
??????? OS_EventWaitListInit(pevent);????????????????????? /* Initialize to 'nobody waiting' on sem.?? */
??? }
??? return (pevent);
}

/*$PAGE*/
/*
*********************************************************************************************************
*???????????????????????????????????????? DELETE A SEMAPHORE
*
* Description: This function deletes a semaphore and readies all tasks pending on the semaphore.
*
* Arguments? : pevent??????? is a pointer to the event control block associated with the desired
*??????????????????????????? semaphore.
*
*????????????? opt?????????? determines delete options as follows:
*??????????????????????????? opt == OS_DEL_NO_PEND?? Delete semaphore ONLY if no task pending
*??????????????????????????? opt == OS_DEL_ALWAYS??? Deletes the semaphore even if tasks are waiting.
*??????????????????????????????????????????????????? In this case, all the tasks pending will be readied.
*
*????????????? err?????????? is a pointer to an error code that can contain one of the following values:
*??????????????????????????? OS_NO_ERR?????????????? The call was successful and the semaphore was deleted
*??????????????????????????? OS_ERR_DEL_ISR????????? If you attempted to delete the semaphore from an ISR
*??????????????????????????? OS_ERR_INVALID_OPT????? An invalid option was specified
*??????????????????????????? OS_ERR_TASK_WAITING???? One or more tasks were waiting on the semaphore
*??????????????????????????? OS_ERR_EVENT_TYPE?????? If you didn't pass a pointer to a semaphore
*??????????????????????????? OS_ERR_PEVENT_NULL????? If 'pevent' is a NULL pointer.
*
* Returns??? : pevent??????? upon error
*????????????? (OS_EVENT *)0 if the semaphore was successfully deleted.
*
* Note(s)??? : 1) This function must be used with care.? Tasks that would normally expect the presence of
*???????????????? the semaphore MUST check the return code of OSSemPend().
*????????????? 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless
*???????????????? they check 'pevent' to see that it's a NULL pointer.
*????????????? 3) This call can potentially disable interrupts for a long time.? The interrupt disable
*???????????????? time is directly proportional to the number of tasks waiting on the semaphore.
*????????????? 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in
*???????????????? applications where the semaphore is used for mutual exclusion because the resource(s)
*???????????????? will no longer be guarded by the semaphore.
*********************************************************************************************************
*/

#if OS_SEM_DEL_EN > 0
OS_EVENT? *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
{
??? BOOLEAN??? tasks_waiting;
??? OS_EVENT? *pevent_return;
#if OS_CRITICAL_METHOD == 3??????????????????????????????? /* Allocate storage for CPU status register */
??? OS_CPU_SR? cpu_sr = 0;
#endif

#if OS_ARG_CHK_EN > 0
??? if (err == (INT8U *)0) {?????????????????????????????? /* Validate 'err'?????????????????????????? */
??????? return (pevent);
??? }
??? if (pevent == (OS_EVENT *)0) {???????????????????????? /* Validate 'pevent'??????????????????????? */
??????? *err = OS_ERR_PEVENT_NULL;
??????? return (pevent);
??? }
#endif
??? if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {??????? /* Validate event block type??????????????? */
??????? *err = OS_ERR_EVENT_TYPE;
??????? return (pevent);
??? }
??? if (OSIntNesting > 0) {??????????????????????????????? /* See if called from ISR ...?????????????? */
??????? *err = OS_ERR_DEL_ISR;???????????????????????????? /* ... can't DELETE from an ISR???????????? */
??????? return (pevent);
??? }
??? OS_ENTER_CRITICAL();
??? if (pevent->OSEventGrp != 0) {???????????????????????? /* See if any tasks waiting on semaphore??? */
??????? tasks_waiting = TRUE;????????????????????????????? /* Yes????????????????????????????????????? */
??? } else {
??????? tasks_waiting = FALSE;???????????????????????????? /* No?????????????????????????????????????? */
??? }
??? switch (opt) {
??????? case OS_DEL_NO_PEND:?????????????????????????????? /* Delete semaphore only if no task waiting */
???????????? if (tasks_waiting == FALSE) {
#if OS_EVENT_NAME_SIZE > 1
???????????????? pevent->OSEventName[0] = '?';???????????? /* Unknown name???????????????????????????? */
???????????????? pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
???????????????? pevent->OSEventType??? = OS_EVENT_TYPE_UNUSED;
???????????????? pevent->OSEventPtr???? = OSEventFreeList; /* Return Event Control Block to free list? */
???????????????? pevent->OSEventCnt???? = 0;
???????????????? OSEventFreeList??????? = pevent;????????? /* Get next free event control block??????? */
???????????????? OS_EXIT_CRITICAL();
???????????????? *err?????????????????? = OS_NO_ERR;
???????????????? pevent_return????????? = (OS_EVENT *)0;?? /* Semaphore has been deleted?????????????? */
???????????? } else {
???????????????? OS_EXIT_CRITICAL();
???????????????? *err?????????????????? = OS_ERR_TASK_WAITING;
???????????????? pevent_return????????? = pevent;
???????????? }
???????????? break;

??????? case OS_DEL_ALWAYS:??????????????????????????????? /* Always delete the semaphore????????????? */
???????????? while (pevent->OSEventGrp != 0) {???????????? /* Ready ALL tasks waiting for semaphore??? */
???????????????? (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
???????????? }
#if OS_EVENT_NAME_SIZE > 1
???????????? pevent->OSEventName[0] = '?';???????????????? /* Unknown name???????????????????????????? */
???????????? pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
???????????? pevent->OSEventType??? = OS_EVENT_TYPE_UNUSED;
???????????? pevent->OSEventPtr???? = OSEventFreeList;???? /* Return Event Control Block to free list? */
???????????? pevent->OSEventCnt???? = 0;
???????????? OSEventFreeList??????? = pevent;????????????? /* Get next free event control block??????? */
???????????? OS_EXIT_CRITICAL();
???????????? if (tasks_waiting == TRUE) {????????????????? /* Reschedule only if task(s) were waiting? */
???????????????? OS_Sched();?????????????????????????????? /* Find highest priority task ready to run? */
???????????? }
???????????? *err?????????????????? = OS_NO_ERR;
???????????? pevent_return????????? = (OS_EVENT *)0;?????? /* Semaphore has been deleted?????????????? */
???????????? break;

??????? default:
???????????? OS_EXIT_CRITICAL();
???????????? *err?????????????????? = OS_ERR_INVALID_OPT;
???????????? pevent_return????????? = pevent;
???????????? break;
??? }
??? return (pevent_return);
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*?????????????????????????????????????????? PEND ON SEMAPHORE
*
* Description: This function waits for a semaphore.
*
* Arguments? : pevent??????? is a pointer to the event control block associated with the desired
*??????????????????????????? semaphore.
*
*????????????? timeout?????? is an optional timeout period (in clock ticks).? If non-zero, your task will
*??????????????????????????? wait for the resource up to the amount of time specified by this argument.
*??????????????????????????? If you specify 0, however, your task will wait forever at the specified
*??????????????????????????? semaphore or, until the resource becomes available (or the event occurs).
*
*????????????? err?????????? is a pointer to where an error message will be deposited.? Possible error
*??????????????????????????? messages are:
*
*??????????????????????????? OS_NO_ERR?????????? The call was successful and your task owns the resource
*??????????????????????????????????????????????? or, the event you are waiting for occurred.
*??????????????????????????? OS_TIMEOUT????????? The semaphore was not received within the specified
*??????????????????????????????????????????????? timeout.
*??????????????????????????? OS_ERR_EVENT_TYPE?? If you didn't pass a pointer to a semaphore.
*??????????????????????????? OS_ERR_PEND_ISR???? If you called this function from an ISR and the result
*??????????????????????????????????????????????? would lead to a suspension.
*??????????????????????????? OS_ERR_PEVENT_NULL? If 'pevent' is a NULL pointer.
*
* Returns??? : none
*********************************************************************************************************
*/

void? OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3?????????????????????????? /* Allocate storage for CPU status register????? */
??? OS_CPU_SR? cpu_sr = 0;
#endif

#if OS_ARG_CHK_EN > 0
??? if (err == (INT8U *)0) {????????????????????????? /* Validate 'err'??????????????????????????????? */
??????? return;
??? }
??? if (pevent == (OS_EVENT *)0) {??????????????????? /* Validate 'pevent'???????????????????????????? */
??????? *err = OS_ERR_PEVENT_NULL;
??????? return;
??? }
#endif
??? if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {?? /* Validate event block type???????????????????? */
??????? *err = OS_ERR_EVENT_TYPE;
??????? return;
??? }
??? if (OSIntNesting > 0) {?????????????????????????? /* See if called from ISR ...??????????????????? */
??????? *err = OS_ERR_PEND_ISR;?????????????????????? /* ... can't PEND from an ISR??????????????????? */
??????? return;
??? }
??? OS_ENTER_CRITICAL();
??? if (pevent->OSEventCnt > 0) {???????????????????? /* If sem. is positive, resource available ...?? */
??????? pevent->OSEventCnt--;???????????????????????? /* ... decrement semaphore only if positive.???? */
??????? OS_EXIT_CRITICAL();
??????? *err = OS_NO_ERR;
??????? return;
??? }
????????????????????????????????????????????????????? /* Otherwise, must wait until event occurs?????? */
??? OSTCBCur->OSTCBStat?? |= OS_STAT_SEM;???????????? /* Resource not available, pend on semaphore???? */
??? OSTCBCur->OSTCBPendTO? = FALSE;
??? 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();
??? if (OSTCBCur->OSTCBPendTO == TRUE) {????????????? /* See if we timedout??????????????????????????? */
??????? OS_EventTO(pevent);
??????? OS_EXIT_CRITICAL();
??????? *err = OS_TIMEOUT;??????????????????????????? /* Indicate that didn't get event within TO????? */
??????? return;
??? }
??? OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
??? OS_EXIT_CRITICAL();
??? *err = OS_NO_ERR;
}
/*$PAGE*/
/*
*********************************************************************************************************
*???????????????????????????????????????? POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments? : pevent??????? is a pointer to the event control block associated with the desired
*??????????????????????????? semaphore.
*
* Returns??? : OS_NO_ERR?????????? The call was successful and the semaphore was signaled.
*????????????? OS_SEM_OVF????????? If the semaphore count exceeded its limit.? In other words, you have
*????????????????????????????????? signalled the semaphore more often than you waited on it with either
*????????????????????????????????? OSSemAccept() or OSSemPend().
*????????????? OS_ERR_EVENT_TYPE?? If you didn't pass a pointer to a semaphore
*????????????? OS_ERR_PEVENT_NULL? If 'pevent' is a NULL pointer.
*********************************************************************************************************
*/

INT8U? OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3??????????????????????????????? /* Allocate storage for CPU status register */
??? OS_CPU_SR? cpu_sr = 0;
#endif

#if OS_ARG_CHK_EN > 0
??? if (pevent == (OS_EVENT *)0) {???????????????????????? /* Validate 'pevent'??????????????????????? */
??????? return (OS_ERR_PEVENT_NULL);
??? }
#endif
??? if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {??????? /* Validate event block type??????????????? */
??????? return (OS_ERR_EVENT_TYPE);
??? }
??? OS_ENTER_CRITICAL();
??? if (pevent->OSEventGrp != 0) {???????????????????????????? /* See if any task waiting for semaphore*/
??????? (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready HPT waiting on event?????????? */
??????? OS_EXIT_CRITICAL();
??????? OS_Sched();??????????????????????????????????????????? /* Find HPT ready to run??????????????? */
??????? return (OS_NO_ERR);
??? }
??? if (pevent->OSEventCnt < 65535u) {??????????????? /* Make sure semaphore will not overflow???????? */
??????? pevent->OSEventCnt++;???????????????????????? /* Increment semaphore count to register event?? */
??????? OS_EXIT_CRITICAL();
??????? return (OS_NO_ERR);
??? }
??? OS_EXIT_CRITICAL();?????????????????????????????? /* Semaphore value has reached its maximum?????? */
??? return (OS_SEM_OVF);
}
/*$PAGE*/
/*
*********************************************************************************************************
*????????????????????????????????????????? QUERY A SEMAPHORE
*
* Description: This function obtains information about a semaphore
*
* Arguments? : pevent??????? is a pointer to the event control block associated with the desired
*??????????????????????????? semaphore
*
*????????????? p_sem_data??? is a pointer to a structure that will contain information about the
*??????????????????????????? semaphore.
*
* Returns??? : OS_NO_ERR?????????? The call was successful and the message was sent
*????????????? OS_ERR_EVENT_TYPE?? If you are attempting to obtain data from a non semaphore.
*????????????? OS_ERR_PEVENT_NULL? If 'pevent'???? is a NULL pointer.
*????????????? OS_ERR_PDATA_NULL?? If 'p_sem_data' is a NULL pointer
*********************************************************************************************************
*/

#if OS_SEM_QUERY_EN > 0
INT8U? OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *p_sem_data)
{
#if OS_LOWEST_PRIO <= 63
??? INT8U???? *psrc;
??? INT8U???? *pdest;
#else
??? INT16U??? *psrc;
??? INT16U??? *pdest;
#endif
??? INT8U????? i;
#if OS_CRITICAL_METHOD == 3??????????????????????????????? /* Allocate storage for CPU status register */
??? OS_CPU_SR? cpu_sr = 0;
#endif

#if OS_ARG_CHK_EN > 0
??? if (pevent == (OS_EVENT *)0) {???????????????????????? /* Validate 'pevent'??????????????????????? */
??????? return (OS_ERR_PEVENT_NULL);
??? }
??? if (p_sem_data == (OS_SEM_DATA *)0) {????????????????? /* Validate 'p_sem_data'??????????????????? */
??????? return (OS_ERR_PDATA_NULL);
??? }
#endif
??? if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {??????? /* Validate event block type??????????????? */
??????? return (OS_ERR_EVENT_TYPE);
??? }
??? OS_ENTER_CRITICAL();
??? p_sem_data->OSEventGrp = pevent->OSEventGrp;?????????? /* Copy message mailbox wait list?????????? */
??? psrc?????????????????? = &pevent->OSEventTbl[0];
??? pdest????????????????? = &p_sem_data->OSEventTbl[0];
??? for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
??????? *pdest++ = *psrc++;
??? }
??? p_sem_data->OSCnt = pevent->OSEventCnt;??????????????? /* Get semaphore count????????????????????? */
??? OS_EXIT_CRITICAL();
??? return (OS_NO_ERR);
}
#endif???????????????????????????????????????????????????? /* OS_SEM_QUERY_EN????????????????????????? */

/*$PAGE*/
/*
*********************************************************************************************************
*????????????????????????????????????????????? SET SEMAPHORE
*
* Description: This function sets the semaphore count to the value specified as an argument.? Typically,
*????????????? this value would be 0.
*
*????????????? You would typically use this function when a semaphore is used as a signaling mechanism
*????????????? and, you want to reset the count value.
*
* Arguments? : pevent???? is a pointer to the event control block
*
*????????????? cnt??????? is the new value for the semaphore count.? You would pass 0 to reset the
*???????????????????????? semaphore count.
*
*????????????? err??????? is a pointer to an error code returned by the function as follows:
*
*??????????????????????????? OS_NO_ERR??????????? The call was successful and the semaphore value was set.
*??????????????????????????? OS_ERR_EVENT_TYPE??? If you didn't pass a pointer to a semaphore.
*??????????????????????????? OS_ERR_PEVENT_NULL?? If 'pevent' is a NULL pointer.
*??????????????????????????? OS_ERR_TASK_WAITING? If tasks are waiting on the semaphore.
*********************************************************************************************************
*/

#if OS_SEM_SET_EN > 0
void? OSSemSet (OS_EVENT *pevent, INT16U cnt, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3?????????????????????????? /* Allocate storage for CPU status register????? */
??? OS_CPU_SR? cpu_sr = 0;
#endif

#if OS_ARG_CHK_EN > 0
??? if (err == (INT8U *)0) {????????????????????????? /* Validate 'err'??????????????????????????????? */
??????? return;
??? }
??? if (pevent == (OS_EVENT *)0) {??????????????????? /* Validate 'pevent'???????????????????????????? */
??????? *err = OS_ERR_PEVENT_NULL;
??????? return;
??? }
#endif
??? if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {?? /* Validate event block type???????????????????? */
??????? *err = OS_ERR_EVENT_TYPE;
??????? return;
??? }
??? OS_ENTER_CRITICAL();
??? *err = OS_NO_ERR;
??? if (pevent->OSEventCnt > 0) {???????????????????? /* See if semaphore already has a count????????? */
??????? pevent->OSEventCnt = cnt;???????????????????? /* Yes, set it to the new value specified.?????? */
??? } else {????????????????????????????????????????? /* No??????????????????????????????????????????? */
??????? if (pevent->OSEventGrp == 0) {??????????????? /*????? See if task(s) waiting?????????????????? */
??????????? pevent->OSEventCnt = cnt;???????????????? /*????? No, OK to set the value????????????????? */
??????? } else {
??????????? *err?????????????? = OS_ERR_TASK_WAITING;
??????? }
??? }
??? OS_EXIT_CRITICAL();
}
#endif

#endif??????????????????????????????????????????????? /* OS_SEM_EN???????????????????????????????????? */

非常好我支持^.^

(3) 100%

不好我反對

(0) 0%

      發表評論

      用戶評論
      評價:好評中評差評

      發表評論,獲取積分! 請遵守相關規定!

      ?
      亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
      <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
      <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
      <acronym id="s8ci2"></acronym>
      <acronym id="s8ci2"><center id="s8ci2"></center></acronym>