?????????????????????????????????????????

??????1??????????????????????????????????????????

??????2???????????????????

??????3??????????????????????????????????????

?????????????????????????????????????????????????е???????????????????????

RAW_U16 raw_mutex_get(RAW_MUTEX *mutex_ptr?? RAW_U32 wait_option)
  {
   RAW_U16 error_status;
   RAW_SR_ALLOC();
 
   #if (RAW_MUTEX_FUNCTION_CHECK > 0)
 
 
   if (mutex_ptr == 0) {
    return RAW_NULL_OBJECT;
   }
 
   if (raw_int_nesting) {
   
    return RAW_NOT_CALLED_BY_ISR;
   
   }
  
   #endif
  
   RAW_CRITICAL_ENTER();
  
    /* mutex is available */
   if (mutex_ptr->count) { 
    mutex_ptr->occupy       =  raw_task_active;                               
    mutex_ptr->occupy_original_priority =  raw_task_active->priority;
    mutex_ptr->count   = 0;
 
    RAW_CRITICAL_EXIT();
 
    return RAW_SUCCESS;
   }
 
 
   /*if the same task get the same mutex again?? it causes deadlock*/
   if (raw_task_active == mutex_ptr->occupy) {   
 
    #if (CONFIG_RAW_ASSERT > 0)
    RAW_ASSERT(0);
    #endif
   
      RAW_CRITICAL_EXIT(); 
    return RAW_MUTEX_DEADLOCK;
     }
 
   /*Cann't get mutex?? and return immediately if wait_option is  RAW_NO_WAIT*/
   if (wait_option == RAW_NO_WAIT) {
 
    RAW_CRITICAL_EXIT();
 
    return RAW_NO_PEND_WAIT;
 
   }
 
   /*system is locked so task can not be blocked just return immediately*/
   if (raw_sched_lock) { 
    RAW_CRITICAL_EXIT();
    return RAW_SCHED_DISABLE;
   }
 
      /*if current task is a higher priority task and block on  the mutex
     *priority inverse condition happened?? priority inherit method is used here*/
  
   if (raw_task_active->priority < mutex_ptr->occupy->priority) {
    switch (mutex_ptr->occupy->task_state) {
    
     case RAW_RDY:
      /*remove from the ready list*/
      remove_ready_list(&raw_ready_queue?? mutex_ptr->occupy);
      /*raise the occupy task priority*/
      mutex_ptr->occupy->priority = raw_task_active->priority;
      /*readd to the ready list head*/
      add_ready_list_head(&raw_ready_queue?? mutex_ptr->occupy);
      break;
    
 
     case RAW_DLY:
     case RAW_DLY_SUSPENDED:
     case RAW_SUSPENDED:
      /*occupy task is not on any list?? so just change the priority*/
      mutex_ptr->occupy->priority = raw_task_active->priority;
      break;
 
     case RAW_PEND:                        /* Change the position of the task in the wait list       */
     case RAW_PEND_TIMEOUT:
     case RAW_PEND_SUSPENDED:
     case RAW_PEND_TIMEOUT_SUSPENDED:
      /*occupy task is on the block list so change the priority on the block list*/
      mutex_ptr->occupy->priority = raw_task_active->priority;
      change_pend_list_priority(mutex_ptr->occupy);
      break;
 
     default:
      RAW_CRITICAL_EXIT();
      return RAW_INVALID_STATE;
    }
   
   }
 
   /*Any way block the current task*/
   raw_pend_object(&mutex_ptr->common_block_obj?? raw_task_active?? wait_option);
 
   RAW_CRITICAL_EXIT();
 
   /*find the next highest priority task ready to run*/
   raw_sched();                                           
 
   /*So the task is waked up?? need know which reason cause wake up.*/
   error_status = block_state_post_process(raw_task_active?? 0);
  
   return error_status;
  }