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

📄 arch_c.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -