📄 tk_crnos.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 + -