⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pro_man.c

📁 PICOS18 V2.10 基于PIC18的实时操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 * @return Status    E_OS_ID if ID is not correct
 *                   never return otherwise
 **********************************************************************/
StatusType ActivateTask (TaskType TaskID)
{
  unsigned char i;
  TaskRefType ptr_task;

  ptr_task = (TaskRefType)&tsk_1_state_ID; 

  for (i = 0; i < MAX_TASK_NB; i++)
  {
    if ( (*ptr_task & MASK_ID) == TaskID )
    {
      if ((*ptr_task & MASK_STATE) == SUSPENDED)
      {
        *ptr_task &= MASK_ID;
        *ptr_task += READY;
        Schedule();
      }
      else
      {
        ptr_task   = (TaskRefType)&tsk_1_activ_prio + i;
        if ((*ptr_task & MASK_ACTIV) < MASK_ACTIV)
          *ptr_task += 0x10;
      }
      return (E_OK);
    }
    ptr_task++;
  }

  return (E_OS_ID);
}

/**********************************************************************
 * Allow a task to terminate itself. Cannot terminate another task.
 * To prepare a new activation of the task, we need first to store in
 * stack the start adress of the task
 *
 * @param dest       OUT Destination buffer 
 * @param src        IN  The byte to copy
 * @return Status    E_OK if ID is not correct
 *                   In fact the function never return 
 **********************************************************************/
StatusType TerminateTask (void)
{
  unsigned char i;
  TaskRefType ptr_task;
   
  ptr_task = (TaskRefType)&tsk_1_state_ID;
   
  for (i = 0; i < MAX_TASK_NB; i++)
  { 
    if ( (*ptr_task & MASK_ID) == id_tsk_run )
    {
	  ptr_task     = (TaskRefType)&tsk_1_activ_prio + i;
	  if ((*ptr_task & MASK_STATE) == 0)
	  {
        ptr_task   = (TaskRefType)&tsk_1_state_ID + i;
        *ptr_task &= MASK_ID;
        *ptr_task += SUSPENDED;
        RESTART;
      }
      else
      {
	    *ptr_task -= 0x10;
        RESTART;
	  }
    }
    ptr_task++;
  }
 
  return (E_OK);
}

/**********************************************************************
 * Chain a task by setting the calling task in a SUSPENDED state and 
 * the called taks in the READY state.
 * Call the scheduler to jump the chained task.
 * This doesn't take into account the multiple activation feature, then
 * if a calling task has been activated twice a chaintask will erased 
 * its activation counter (the calling task will be SUSPENDED).
 *
 * @param TaskID     IN  ID of the next task to chain
 * @return Status    E_OK if ID is not correct
 *                   In fact the function never return 
 **********************************************************************/
StatusType ChainTask (TaskType TaskID)
{
  unsigned char i;
  TaskRefType ptr_task;

  ptr_task = (TaskRefType)&tsk_1_state_ID;

  for (i = 0; i < MAX_TASK_NB; i++)
  {
    if ( (*ptr_task & MASK_ID) == id_tsk_run )
    {
      *ptr_task &= MASK_ID;
      *ptr_task += SUSPENDED;
    }
    if ( (*ptr_task & MASK_ID) == TaskID )
    {
      *ptr_task &= MASK_ID;
      *ptr_task += READY;
    }
    ptr_task++;
  }
  
  RESTART;
  return (E_OK);
}

/**********************************************************************
 * Force a scheduler action
 *
 * @return Status    E_OK if a service is called inside an ISR
 *                   or never returns
 **********************************************************************/
StatusType Schedule(void)
{
  INTCONbits.GIEL = 0;
  kernelState |= SERVICES;
  if (kernelState & ISR)
    return (E_OK);
  kernelState &= ~SERVICES;
  if (kernelState & USER)
    SAVE_TASK_CTX(stack_low, stack_high);
  SCHEDULE;
  return (E_OK);
}

/**********************************************************************
 * Return the appmode global variable.
 *
 * @return AppMode   The mode set by application 
 **********************************************************************/
AppModeType GetActiveApplicationMode(void)
{
  return(appmode);
}

/**********************************************************************
 * Jump to the KERNEL code area by setting the appmode global variable. 
 * This service is for call from main routine only.
 * Store at first the return adress in main routine.
 *
 * @param Mode       IN  Mode to set into appmode
 * @return void
 **********************************************************************/
void StartOS(AppModeType Mode)
{
  SAVE_TASK_CTX(FSR1L, FSR1H);
  FSR1L_MAIN = FSR1L;
  FSR1H_MAIN = FSR1H;
  appmode = Mode;
  STKPTR = 0;
  _asm	goto _kernel  _endasm;
}

/**********************************************************************
 * Stop the kernel and task activation after an error occurs. 
 * The function returns to the adress of the main function stored by 
 * the StartOS service.
 *
 * @param error      IN  Last error number detected
 * @return void
 **********************************************************************/
void ShutdownOS(StatusType Error)
{	
#ifdef	SHUTDOWNHOOK
  ShutdownHook(Error);
#endif
  FSR1L = FSR1L_MAIN;
  FSR1H = FSR1H_MAIN;  
  _restore_now();
}

/**********************************************************************
 * Force the kernel to bring into order the list of tasks function to  
 * priority.
 *
 * @param  void
 * @return void
 **********************************************************************/
void Organize(void)
{
  SAVE_TASK_CTX(stack_low, stack_high);
  ORGANIZE;
}

/**********************************************************************
 * Set the task priority to the resource priority. 
 * See the ceiling protocol of the OSEK/VDX standart.
 *
 * @param ID         IN  ID of the resource to be accessed
 * @return Status    E_OS_ACCESS if the resource does not exist
 *                   Elsewise the function never returns 
 **********************************************************************/
StatusType GetResource(ResourceType ID)
{
  if (ID >= RESOURCENUMBER)
    return (E_OS_ID);
  if (Resource_list[ID].lock == 1)
    return E_OS_ACCESS;
  GetPriority(&Resource_list[ID].Taskprio, id_tsk_run);
  SetPriority(Resource_list[ID].priority, id_tsk_run);
  Resource_list[ID].lock = 1;
  Organize();
  return(E_OK);
}

/**********************************************************************
 * Restore the task priority to original value. 
 * See the ceiling protocol of the OSEK/VDX standart.
 *
 * @param ID         IN  ID of the resource to be accessed
 * @return Status    E_OS_ACCESS if the resource does not exist
 *                   Elsewise the function never returns 
 **********************************************************************/
StatusType ReleaseResource(ResourceType ID)
{
  if (ID >= RESOURCENUMBER)
    return (E_OS_ID);
  if (Resource_list[ID].lock == 0)
    return E_OS_ACCESS;
  SetPriority(Resource_list[ID].Taskprio, id_tsk_run);
  Resource_list[ID].lock = 0;
  Organize();
  return(E_OK);
}


/* End of File : pro_man.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -