📄 pro_man.c
字号:
* @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 + -