📄 os_cpu_c.c
字号:
/*
*********************************************************************************************************
* System Reset
*
* Description: This function can be called by any task and will call the system reset hook function. This* hook function should be defined by the application if the flag OS_SYSTEM_RESET_EN is set.
*
* Arguments : none
*********************************************************************************************************
*/
void OSSystemReset(void)
{#if OS_SYSTEM_RESET_EN > 0 /* Stop alarm for system reset */ alarm(0); /* Call application defined system reset hook */ OSSystemResetHook(); /* Start alarms */ InitTick();#endif
}
/*
*********************************************************************************************************
* START MULTITASKING
*
* Description: This function is used to start the multitasking process which lets uC/OS-II manages the
* task that you have created. Before you can call OSStart(), you MUST have called OSInit()
* and you MUST have created at least one task.
*
* Arguments : none
*
* Returns : none
*
* Note : OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Set OSRunning to TRUE.
* c) Load the context of the task pointed to by OSTCBHighRdy.
* d_ Execute the task.
*********************************************************************************************************
*/
void OSStartHighRdy(void)
{
OSTaskSwHook();
OSRunning = OS_TRUE;
/* Wait until all task wrappers have started */
pthread_mutex_lock (&mutThread);
if( nNumThreadsCreated != nNumThreadsStarted )
pthread_cond_wait (&cvThreadWrapper, &mutThread);
pthread_mutex_unlock (&mutThread); /* All tasks are ready so start interrupts */ InitTick(); /* Get pointer highest priority thread */
FuncInfo* pFuncInfo = (FuncInfo*)OSTCBCur->OSTCBStkPtr;
/* Let highest prio thread go */
pthread_mutex_lock( &mutThread );
pthread_cond_signal( &grcvThread[ pFuncInfo->nThreadIdx ] );
pthread_mutex_unlock( &mutThread ); /* Main thread must be kept going otherwise process turns into zombie */ while(1);
}
/*
*********************************************************************************************************
* Interrupt Context Switch
*
* Description: Context switch from an interrupt.
*
* Arguments : none
*********************************************************************************************************
*/
void OSIntCtxSw(void)
{ /* Grab task switching mutex */
pthread_mutex_lock( &mutThread );
/* Get ptrs to new and old context */
FuncInfo* pFuncInfoNew = (FuncInfo*)OSTCBHighRdy->OSTCBStkPtr;
FuncInfo* pFuncInfoOld = (FuncInfo*)OSTCBCur->OSTCBStkPtr;
/* Set current context to highest priority */
OSTCBCur = OSTCBHighRdy;
OSPrioCur = OSPrioHighRdy;
/* Signal highest priority thread to start by setting its condition variable */
pthread_cond_signal( &grcvThread[ pFuncInfoNew->nThreadIdx ] );
/* Wait for this threads condition variable to change ( i.e. the next ctx switch ). */
pthread_cond_wait( &grcvThread[ pFuncInfoOld->nThreadIdx ], &mutThread );
/* Variable change automatically locks mutex, so unlock */
pthread_mutex_unlock( &mutThread );
}
/*
*********************************************************************************************************
* Task Context Switch
*
* Description: Context switch from a task. This just calls the context switch for an interrupt, they are
* identical.
*
* Arguments : none
*********************************************************************************************************
*/void OSCtxSw(){ OSIntCtxSw();}/*
*********************************************************************************************************
* OSTickISR
*
* Description: This function processes time ticks.
*
* Arguments : none
*********************************************************************************************************
*/
void OSTickISR(void)
{
OSIntEnter();
OSTimeTick();
OSIntExit();
}
/**********************************************************************************************************
* AlarmSigHandler
*
* Description: This function is called when ever a interrupt is delivered.
*
* Arguments : none of these args are used.
*********************************************************************************************************
*/
//void AlarmSigHandler(int signo, siginfo_t* info, void* uc)void AlarmSigHandler( int signum )
{
OSTickISR();
}
/*
*********************************************************************************************************
* InitTick
*
* Description: This function starts the alarm interrupt at the appropriate frequency. Note: Linux can only* deliver 10ms resolution on this alarm even though it is set in usecs.
*
* Arguments : none
*********************************************************************************************************
*/
static void InitTick()
{
ualarm(1000000/OS_TICKS_PER_SEC, 1000000/OS_TICKS_PER_SEC);
}
/*
*********************************************************************************************************
* ThreadWrapper
*
* Description: Every Task is wrapped with this function. When the tasks thread is first created it executes* this wrapper function which stops the thread from executing.
*
* Arguments : pTaskInfo Pointer to a FuncInfo structure. This structure holds the information about* the task that should be exectued in this thread.
*********************************************************************************************************
*/
void ThreadWrapper(void* pTaskInfo)
{ /* Grab thread index */
int nThreadIdx = (( FuncInfo* )( pTaskInfo ))->nThreadIdx;
/* Wait until task switching mutex is available */
pthread_mutex_lock( &mutThread );
/* Increment the number of task wrappers that have started */
nNumThreadsStarted++;
/* Signal if all wrappers have started */
if( nNumThreadsCreated == nNumThreadsStarted )
pthread_cond_signal( &cvThreadWrapper );
/* Wait on this threads condition variable and unlock task switching mutex */
pthread_cond_wait( &grcvThread[ nThreadIdx ], &mutThread );
pthread_mutex_unlock( &mutThread );
/* Unblock alarm signals. */
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGALRM);
sigprocmask(SIG_UNBLOCK, &set, 0);
pF = (( FuncInfo* )( pTaskInfo ))->pFunc;
( *pF )( (( FuncInfo* )( pTaskInfo ))->pArgs );
}
/*
*********************************************************************************************************
* OSTCBInitHook
*
* Description: Initializes the task by creating a thread for that task. The thread information was stored
* on the stack during. This Linux port requires OSTCBInitHook and must have OS_VERSION >= 204.
*
* Arguments : ptcb pointer to a task control block. Contains all the info for the task.
*********************************************************************************************************
*/
void OSTCBInitHook(OS_TCB *ptcb)
{#if OS_VERSION >= 204
/* Grab task info that was previously stored on task stack */
FuncInfo* pFuncInfo = (FuncInfo*)ptcb->OSTCBStkPtr;
/* Store index of thread and condition variable on stk for use in ctx switching */
pFuncInfo->nThreadIdx = nNumThreadsCreated;
nNumThreadsCreated++;
/* Initialize thread condition variable and create thread */
pthread_cond_init(&grcvThread[ pFuncInfo->nThreadIdx ], NULL);
pthread_create(&threadTask[ pFuncInfo->nThreadIdx ], NULL, (void*)&ThreadWrapper, (void*)(pFuncInfo) );#endif
}
/*
*********************************************************************************************************
* InitLinuxPort
*
* Description: Creates the signal handler for the alarm interrupt. Blocks all alarm signals, threads will
* also inherit this blocking when they are created. Sets up context switching mutex.
*
* Arguments : none
*********************************************************************************************************
*/
static void InitLinuxPort()
{
//setup signal handlers
struct sigaction act;
sigset_t mask;
sigemptyset(&mask);
act.sa_sigaction = (void*)AlarmSigHandler;
act.sa_flags = 0;
act.sa_mask = mask;
if ( sigaction(SIGALRM, &act, NULL) )
printf("Sigaction failed for SIGALRM\n" );
//Block all signals in this the main thread. It should not call any signal handler
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGALRM);
sigprocmask(SIG_BLOCK, &set, 0);
// Setup context switching mutex
pthread_mutex_init(&mutThread, NULL);
pthread_cond_init (&cvThreadWrapper, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -