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

📄 tk_crnos.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/*
 * FILENAME: tk_crnos.c
 *
 * Copyright  2002 By InterNiche Technologies Inc. All rights reserved
 *
 * Wrapper and utility Functions to map NicheTask "TK_" macros to ChronOS
 *
 * MODULE: MISCLIB
 *
 * PORTABLE: yes (within ChronOS & uCOS systems)
 *
 * These wrapper functions for native ChronOS functions are dependant on the
 * the implemenation of the project/target directory osport.c file.
 *
 */

#include "ipport.h"

#ifdef CHRONOS

#include OSPORT_H

extern int num_net_tasks;
extern struct inet_taskinfo nettasks[];

void     TK_OSTaskResume(u_char * Id);
void     TK_OSTimeDly(void);
u_char   TK_OSTaskQuery(void);

void TK_OSTimeDly(void)
{
   OSTimeDly(2);
}

void TK_OSTaskResume(u_char * Id)
{
INT8U err;

   err = OSTaskResume(*Id);
   
   if ((err != OS_NO_ERR) && (err != OS_TASK_NOT_SUSPENDED))
   {
      dprintf("ChronOS API call failure, to Resume Suspeded Task!\n");
      dtrap("tk_crnos 0\n");
      panic("TK_OSTaskResume");      
   }
   return;
}

extern INT8U netmain_prio;

/* SignalPktDemux() for ChronOS is a routine which manually sets the net
 * task to runnable. This is so we can call it from an ISR and not loose
 * control to ChronOS at ISR time.
 */

void
SignalPktDemux(void)
{
   OS_TCB * nettask;

   nettask = OSTCBPrioTbl[netmain_prio];

   /* Wake netmain task */
   nettask->OSTCBStat &= ~OS_STAT_SUSPEND;   /* clear "suspend" bit */
   nettask->OSTCBDly = 0;                    /* Cancel any delay */
   OSRdyGrp |= nettask->OSTCBBitY;           /* Make task ready to run */
   OSRdyTbl[nettask->OSTCBY] |= nettask->OSTCBBitX;
}


#ifndef TCPWAKE_RTOS

void
tcp_sleep(void * event)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
   OS_CPU_SR  cpu_sr;
#endif

   OSTCBCur->tcp_event = event;     /* record pointer we are sleeping on */

   /* Calling OSTaskSuspend() after UNLOCK_NET_RESOURCE(NET_RESID) leaves
    * a time interval where the tcp_wakeup() call for the event can occur
    * before the task is really suspended. To avoid this, we directly set
    * the bit to suspend the task, then free the NET_RESID semaphore and
    * call OS_Sched().
    */

   OS_ENTER_CRITICAL();
   /* Make task not ready */
   if( (OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00)
   {    
      OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
   }
   OSTCBCur->OSTCBStat |= OS_STAT_SUSPEND;  /* Status is 'SUSPENDED'*/
   
   /* (yaxon add) */
#if OS_TASKGROUP_EN > 0
    OSTaskGroupTbl[OSTCBCur->OSTaskGroup] = 0xFF; /* Clear Task Group */
#endif
   
   UNLOCK_NET_RESOURCE(NET_RESID);  /* Exiting net code (into suspension) */
   OS_EXIT_CRITICAL();

   OS_Sched();                      /* turn control over to OS */
   LOCK_NET_RESOURCE(NET_RESID);    /* re-entering net code */
}

void
tcp_wakeup(void * event)
{
   int         i;          /* task table index */
   int         wakeups;    /* number of tasks we woke up */
   OS_TCB *    tp;

   wakeups = 0;

   /* Loop through task table, making each task with the event flag
    * set ready to run. DOn;t both check the last (Idle) task.
    */
   for(i = 0; i < OS_LOWEST_PRIO; i++)
   {
      if(OSTCBPrioTbl[i]->tcp_event == event)
      {
         tp = OSTCBPrioTbl[i];               /* get pointer to task */
         tp->OSTCBStat &= ~OS_STAT_SUSPEND;  /* clear "suspend" bit */
         tp->OSTCBDly = 0;                   /* Cancel any delay */
         OSRdyGrp |= tp->OSTCBBitY;          /* Make task ready to run */
         OSRdyTbl[tp->OSTCBY] |= tp->OSTCBBitX;
         tp->tcp_event = NULL;               /* clear wakeup event */
         wakeups++;
      }
   }
   /* If we woke any tasks then call the scheduler */
   if(wakeups)
      OS_Sched();

   return;
}

#else   /* TCPWAKE_RTOS */

u_char TK_OSTaskQuery(void)
{
OS_TCB task_data;
INT8U err, task_prio;

   err = OSTaskQuery(OS_PRIO_SELF, &task_data);

   if (err == OS_NO_ERR)
   {
      task_prio = task_data.OSTCBPrio;
   }
   else
   {
      dprintf("ChronOS API call failure, unable to identify task!");
      panic("TK_OSTaskQuery");
      return 0;
   }
   
   return task_prio;
}

#endif   /* TCPWAKE_RTOS */


void
tk_yield(void)
{
   int   lower_ready;    /* index to next lower ready table */
   
   /* To avoid pointless and lengthy delays to the calling task, ONLY
    * do this if there is another task of similar priority ready to run.
    * We check this tasks OSRdyTbl[] entry, and the next entry down. In
    * this task's entry we expect to find only our own bit set, the other
    * should have no bits set. If any of these bite are set then we call
    * OSTimeDly() to give them a chance to run.
    */

   lower_ready = OSTCBCur->OSTCBY + 1;

   if((OSRdyTbl[OSTCBCur->OSTCBY] != OSTCBCur->OSTCBBitX) ||
      (OSRdyTbl[lower_ready]))
   {
      /* To ensure cycles to the lower priority tasks we should really
       * delay by two ticks, but that really hurts performance on some
       * long-tick targets. One tick works better overall....
       */
      OSTimeDly(1);
   }
   return;
}


extern struct inet_taskinfo * nettask;
extern int num_net_tasks;

static char * app_text = "app";

int
tk_stats(void * pio)
{
   int      i;    /* index into generic nettasks table */
   int      t;    /* index into ChronOS TCB table */
   OS_TCB * tcb;  /* ChronOS Task Control Block */
   OS_STK * sp;   /* scratch stack pointer */
   int      stackuse;
   char *   name;
   

   ns_printf(pio, "ChronOS RTOS stats:\n");
   ns_printf(pio, "Context switches; Delay:  %lu, Interrupt: %lu\n",
      OSCtxSwCtr, OSCtxIntCtr);

   ns_printf(pio, "       name     prio. state    wakeups stack-size stack-use \n");

   
   for(t = 0; t <= OS_LOWEST_PRIO ; t++)
   {
      /* get pointer to TCB and see if entry is in use */
      tcb = OSTCBPrioTbl[t];
      if(tcb == NULL)
         continue;

      if(t == OS_LOWEST_PRIO)    /* lowest priority is alwasy IDLE task */
         name = "idle";
      else if(t == (OS_LOWEST_PRIO-1))    /* next lowest may be stats task */
         name = "stats";
      else
         name = app_text;           /* default name to application */

      /* See if we can find name for this in our "core task" array. This
       * may overwrite the "stats" task name if there is no stats task
       * and the priority is in use by an applcation.
       */
      for(i = 0; i < num_net_tasks; i++)
      {
         if(nettasks[i].priority == tcb->OSTCBPrio)
         {
            name = nettasks[i].name;
            break;
         }
      }

      ns_printf(pio, "%15s %2d    0x%04x, %9ld, ",
         name, tcb->OSTCBPrio, tcb->OSTCBStat, tcb->wakeups);

      /* Find lowest non-zero value in stack so we can estimate the
       * unused portion. Subtracting this from size gives us the used
       * portion of the stack.
       */
#if OS_TASK_CREATE_EXT_EN > 0
      if(tcb->OSTCBStkBottom && tcb->OSTCBStkSize)
      {
         sp = tcb->OSTCBStkBottom + 1;
         while(*sp == 0)
            sp++;
         /* This OS traditionally keeps the size in OS_STK (int) units rather
          * than bytes, so convert back to bytes for display.
          */
         stackuse = (tcb->OSTCBStkSize - (sp - tcb->OSTCBStkBottom)) * sizeof(OS_STK);
         ns_printf(pio, "%6d,      %6d\n",
            tcb->OSTCBStkSize * sizeof(OS_STK),  stackuse);
      }
      else
#endif
      {
         ns_printf(pio, "No stack data\n");
      }
   }

   return 0;
}


#endif /* CHRONOS */

⌨️ 快捷键说明

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