📄 arch_c.c
字号:
SetThreadPriority(GetCurrentThread(), thistask->priority);
(thistask->firstfunc)(thistask->taskarg);
#if (POSCFG_FEATURE_EXIT != 0)
posTaskExit();
#endif
assert(0);
return 0;
}
static void a_createThisTask(TASKPRIV_t thistask)
{
thistask->suspendSema = CreateSemaphore(NULL, 0, 1, NULL);
assert(thistask->suspendSema != NULL);
thistask->state = task_exist;
thistask->ownTaskHandle = CreateThread(
NULL, thistask->stacksize, a_newThread,
thistask, 0, &thistask->ownTaskID);
assert(thistask->ownTaskHandle != NULL);
}
static void a_quitThisTask(TASKPRIV_t thistask)
{
if (thistask->suspendSema != NULL)
{
CloseHandle(thistask->suspendSema);
thistask->suspendSema = NULL;
}
thistask->state = task_terminated;
ExitThread(0);
}
static void a_initTask(POSTASK_t task, UINT_t stacksize,
POSTASKFUNC_t funcptr, void *funcarg)
{
TASKPRIV_t newtask = GETTASKPRIV(task);
newtask->state = task_mustcreate;
newtask->ownTaskID = 0;
newtask->ownTaskHandle= NULL;
newtask->suspendSema = NULL;
newtask->stacksize = (stacksize>MIN_STACKSIZE)? stacksize:MIN_STACKSIZE;
newtask->firstfunc = funcptr;
newtask->taskarg = funcarg;
newtask->priority = THREAD_PRIORITY_BELOW_NORMAL;
if (!idleTaskCreated_g)
{
newtask->priority = THREAD_PRIORITY_IDLE;
idleTaskCreated_g = 1;
}
newtask->blockIntFlag = 0;
}
/*---------------------------------------------------------------------------
* TIMER INTERRUPT
*-------------------------------------------------------------------------*/
static void a_timerTask(void)
{
for(;;)
{
/* wait for the timer event */
if (timerEvent_g != NULL)
{
Sleep(500/HZ);
SemaWait(timerEvent_g);
}
else
{
Sleep(1000/HZ);
}
/* execute the timer interrupt */
callInterruptHandler( c_pos_timerInterrupt );
}
}
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS
*-------------------------------------------------------------------------*/
/*-------- PORT INITIALIZATION --------*/
void p_pos_initArch(void)
{
if (!archInitialized_g)
{
assert(TASK_RESERVED_PORT_MEM >= sizeof(struct TASKPRIV_s));
interruptWaitSem_g = CreateSemaphore(NULL, 0, 1, NULL);
assert(interruptWaitSem_g != NULL);
globalSyncSem_g = CreateSemaphore(NULL, 1, 1, NULL);
assert(globalSyncSem_g != NULL);
windowsThreadSyncMutex_g = CreateMutex(NULL, FALSE, NULL);
assert(windowsThreadSyncMutex_g != NULL);
idleTaskSuspendSem_g = CreateSemaphore(NULL, 0, 1, NULL);
assert(idleTaskSuspendSem_g != NULL);
timerEvent_g = NULL;
taskLockCnt_g = 0;
blockInterrupt_g = 0;
interruptTaskId_g = 0;
intlevelCounter_g = 0;
idleTaskCreated_g = 0;
cpuIdleFlag_g = 0;
interruptWaiting_g = 0;
interruptActive_g = 0;
interruptExecuting_g = 0;
archInitialized_g = 1;
}
}
/*-------- TASK STRUCTURE SETUP --------*/
#if (POSCFG_TASKSTACKTYPE == 0)
void p_pos_initTask(POSTASK_t task, void *user,
POSTASKFUNC_t funcptr, void *funcarg)
{
(void) user;
a_initTask(task, MIN_STACKSIZE, funcptr, funcarg);
}
#elif (POSCFG_TASKSTACKTYPE == 1)
VAR_t p_pos_initTask(POSTASK_t task, UINT_t stacksize,
POSTASKFUNC_t funcptr, void *funcarg)
{
a_initTask(task, stacksize, funcptr, funcarg);
return 0;
}
#elif (POSCFG_TASKSTACKTYPE == 2)
VAR_t p_pos_initTask(POSTASK_t task,
POSTASKFUNC_t funcptr, void *funcarg)
{
a_initTask(task, MIN_STACKSIZE, funcptr, funcarg);
return 0;
}
#else
#error POSCFG_TASKSTACKTYPE
#endif
void p_pos_freeStack(POSTASK_t task)
{
TASKPRIV_t tp = GETTASKPRIV(task);
tp->state = task_mustquit;
}
/*-------- CONTEXT SWITCHING --------*/
void p_pos_softContextSwitch(void)
{
TASKPRIV_t thistask = GETTASKPRIV(posCurrentTask_g);
TASKPRIV_t nexttask = GETTASKPRIV(posNextTask_g);
TSTATE_t state = thistask->state;
assert(interruptExecuting_g == 0);
assert(GetCurrentThreadId() == thistask->ownTaskID);
assert(thistask != nexttask);
assert(taskLockCnt_g != 0);
/* wake the idle task
(quick-and-dirty to get things working as expected) */
if (cpuIdleFlag_g != 0)
{
cpuIdleFlag_g = 0;
SemaSignal(idleTaskSuspendSem_g);
}
/* swap context variable */
posCurrentTask_g = posNextTask_g;
/* start next task */
if (nexttask->state == task_exist)
{
SemaSignal(nexttask->suspendSema);
}
else
if (nexttask->state == task_interrupted)
{
Sleep(0);
SemaWait(globalSyncSem_g);
assert(taskLockCnt_g == 1);
blockInterrupt_g = nexttask->blockIntFlag;
nexttask->state = task_exist;
p_pos_globalUnlock(-1);
assert( ResumeThread(nexttask->ownTaskHandle) == 1 );
SemaSignal(globalSyncSem_g);
}
else
if (nexttask->state == task_mustcreate)
{
SemaWait(globalSyncSem_g);
assert(taskLockCnt_g == 1);
p_pos_globalUnlock(-1);
a_createThisTask(nexttask);
SemaSignal(globalSyncSem_g);
}
else assert(0);
/* suspend current task */
if (state == task_exist)
{
SemaWait(thistask->suspendSema);
}
else
if (state == task_mustquit)
{
a_quitThisTask(thistask);
}
else assert(0);
assert(taskLockCnt_g != 0);
}
void p_pos_intContextSwitch(void)
{
TASKPRIV_t thistask = GETTASKPRIV(posCurrentTask_g);
TASKPRIV_t nexttask = GETTASKPRIV(posNextTask_g);
int i;
assert(thistask->state == task_exist);
/* avoid race condition: wait until just started task is up */
i = 0;
while (thistask->ownTaskHandle == NULL)
{
Sleep(i);
if (++i > 100) i = 100;
}
/* suspend the currently active task */
assert( SuspendThread(thistask->ownTaskHandle) == 0 );
thistask->state = task_interrupted;
thistask->blockIntFlag = blockInterrupt_g;
blockInterrupt_g = 0;
/* start next task */
posCurrentTask_g = posNextTask_g;
if (nexttask->state == task_exist)
{
taskLockCnt_g = 1;
interruptActive_g = 0;
interruptExecuting_g = 0;
SemaSignal(nexttask->suspendSema);
}
else
if (nexttask->state == task_interrupted)
{
assert(taskLockCnt_g == 0);
interruptActive_g = 0;
interruptExecuting_g = 0;
blockInterrupt_g = nexttask->blockIntFlag;
nexttask->state = task_exist;
assert( ResumeThread(nexttask->ownTaskHandle) == 1 );
}
else
if (nexttask->state == task_mustcreate)
{
assert(taskLockCnt_g == 0);
interruptActive_g = 0;
interruptExecuting_g = 0;
a_createThisTask(nexttask);
}
else assert(0);
}
void p_pos_startFirstContext(void)
{
TASKPRIV_t firsttask;
/* Set this thread to high priority. This thread will do the timer IRQ. */
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
/* Start the first pico]OS task (=first context). */
SemaWait(globalSyncSem_g);
p_pos_globalUnlock(-1);
firsttask = GETTASKPRIV(posCurrentTask_g);
a_createThisTask(firsttask);
SemaSignal(globalSyncSem_g);
/* OK. We continue with doing the timer interrupt. */
a_initTimer();
a_timerTask();
}
void p_pos_idleTaskHook(void)
{
/* the idle task gives of processing time here */
cpuIdleFlag_g = 1;
SemaWait(idleTaskSuspendSem_g);
}
/*-------- GLOBAL INTERRUPT LOCKING --------*/
void p_pos_globalLock(int *flags)
{
TASKPRIV_t thistask = GETTASKPRIV(posCurrentTask_g);
DWORD curthread = GetCurrentThreadId();
int i;
if (!archInitialized_g) p_pos_initArch();
if (interruptTaskId_g != curthread)
{
if (posRunning_g)
assert(thistask->ownTaskID == curthread);
i = 0;
blockInterrupt_g = 1;
barrier();
while (interruptActive_g || interruptExecuting_g)
{
blockInterrupt_g = 1;
Sleep(i);
if (++i > 100) i = 100;
}
assert(interruptExecuting_g == 0);
*flags = taskLockCnt_g;
taskLockCnt_g++;
barrier();
blockInterrupt_g = 0;
}
else
{
*flags = taskLockCnt_g;
}
}
void p_pos_globalUnlock(int flags)
{
TASKPRIV_t thistask = GETTASKPRIV(posCurrentTask_g);
DWORD curthread = GetCurrentThreadId();
if (interruptTaskId_g != GetCurrentThreadId())
{
assert(taskLockCnt_g > 0);
assert(taskLockCnt_g != flags);
assert(interruptExecuting_g == 0);
if (posRunning_g && (flags >= 0))
assert(thistask->ownTaskID == curthread);
if (taskLockCnt_g > 1)
{
assert(flags != 0);
taskLockCnt_g--;
}
else
{
assert(flags <= 0);
taskLockCnt_g = 0;
if (interruptWaiting_g)
{
interruptWaiting_g = 0;
SemaSignal(interruptWaitSem_g);
Sleep(0);
}
}
}
}
/*---------------------------------------------------------------------------
* NANO LAYER INTERFACE FUNCTIONS
*-------------------------------------------------------------------------*/
#if POSCFG_ENABLE_NANO
UVAR_t p_putchar(char c)
{
putchar(c);
return 1;
}
static void a_keyboardInput(void)
{
#if NOSCFG_FEATURE_CONIN
static int ctr = 0;
UVAR_t c;
if (++ctr >= (HZ/20))
{
ctr = 0;
while (_kbhit())
{
c = (UVAR_t) _getch();
if (c)
{
c_nos_keyinput(c);
}
}
}
#endif
}
#endif /* POSCFG_ENABLE_NANO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -