📄 tinyworks.c
字号:
#include "TinyWorks.h"
#include "port.h"
// 就绪任务表
TW_TCB *pTaskTCB[16];
// 挂起任务表
TW_TCB *pSpdTCB[16];
// 当前任务、新当前任务
TW_TCB *pCurrent, *pNew;
// 系统时钟,如果1毫秒中断一次,49天溢出一次
volatile u32 TWTimeTick;
// 空闲计数,8192Mips速度的CPU,一秒钟才有可能会溢出一次
volatile u32 TWIdelTick;
Stk_t IdelTaskStack[70];
TW_TCB IdelTaskTcb;
void TWIdelTask( void );
/******************************************************************************
*
* 系统数据的初始化
*
******************************************************************************/
void TWInit( void )
{
u16 i;
for(i=0; i<16; i++)
{
pTaskTCB[i] = (TW_TCB*)0;
pSpdTCB[i] = (TW_TCB*)0;
}
pCurrent = (TW_TCB*)0;
pNew = (TW_TCB*)0;
TWTimeTick = 0;
TWIdelTick = 0;
TWCreate( &IdelTaskTcb, TWIdelTask, IdelTaskStack+69, 15 );
}
/******************************************************************************
*
* 建立任务
* Tcb: 任务控制块
* pTask: 任务函数
* StkTop: 堆栈顶部(堆栈起始地址+堆栈大小-1)
* Proith: 任务优先级
*
******************************************************************************/
void TWCreate( TW_TCB *Tcb, CFUNC pTask, Stk_t *StkTop, u8 Proity )
{
TW_TCB *loc_tcb;
Stk_Init(Tcb, pTask, StkTop); // 初始化堆栈
Tcb->Ticks = 0; // 初始化时钟滴哒
Tcb->Next = (void *)0;
loc_tcb = pTaskTCB[Proity&0x0F];
if (loc_tcb == (TW_TCB*)0)
{
pTaskTCB[Proity&0x0F] = Tcb; // 若此优先级没有任务,则直接建立到此优先级的表里
}
else
{
while(loc_tcb->Next != (void*)0)
{
loc_tcb = (TW_TCB*)loc_tcb->Next;
}
loc_tcb->Next = (void*)Tcb; // 若此优先级有任务,则建立到此优先级的表的尾部
}
}
/******************************************************************************
*
* 时间服务,用在定时中断里
*
******************************************************************************/
void TWTimerTick( void )
{
u16 i;
TW_TCB *loc_tcb, *loc_tcb1;
disable();
TWTimeTick ++;
enable();
for(i=0; i<16; i++)
{
loc_tcb = pSpdTCB[i];
loc_tcb1 = loc_tcb;
while(loc_tcb != (TW_TCB*)0)
{
disable();
if (loc_tcb->Ticks > 0)
{
loc_tcb->Ticks --;
}
if (loc_tcb->Ticks == 0) // 如果正在被扫描的任务延时达到
{
if (loc_tcb != loc_tcb1) // 从挂起表内摘除该就绪任务
{
loc_tcb1->Next = loc_tcb->Next;
}
else
{
pSpdTCB[i] = (TW_TCB*)loc_tcb->Next;
}
loc_tcb->Next = (void*)0; // 断尾
if (pTaskTCB[i] == (TW_TCB*)0) // 放该任务于就绪表的尾部
{
pTaskTCB[i] = loc_tcb;
}
else
{
loc_tcb1 = pTaskTCB[i];
while(loc_tcb1->Next != (TW_TCB*)0)
{
loc_tcb1 = (TW_TCB*)loc_tcb1->Next;
}
loc_tcb1->Next = (void*)loc_tcb;
}
}
loc_tcb1 = loc_tcb;
loc_tcb = (TW_TCB*)loc_tcb1->Next;
enable();
} // 遍历所有任务,对任务时间进行管理
}
}
/******************************************************************************
*
* 任务调度,用在定时中断里
*
******************************************************************************/
void TWSched( void )
{
u16 i;
TW_TCB *loc_tcb;
for(i=0; i<16; i++)
{
disable();
if (pTaskTCB[i]!=(TW_TCB*)0) // 找到了最高优先级的就绪任务
{
if (pTaskTCB[i]!=pCurrent) // 不是当前运行的任务
{
pNew = pTaskTCB[i]; // 直接把当前运行的任务换成该任务
enable();
}
else if (pCurrent->Next != 0) // 如果最新就绪的任务是最高优先级的任务,如果该优先级没有其它任务,则置之不理
{
loc_tcb = pCurrent;
while(loc_tcb->Next != 0) // 遍历整个优先级表,找到尾部
{
loc_tcb = (TW_TCB*)loc_tcb->Next;
}
loc_tcb->Next = (void *)pTaskTCB[i]; // 当前任务放在尾部
pTaskTCB[i] = (TW_TCB*)pTaskTCB[i]->Next; // 指向下一个任务
pCurrent->Next = (void*)0; // 断尾
pNew = pTaskTCB[i]; // 指向就绪表的第一个任务
}
break;
}
enable();
}
enable();
}
/******************************************************************************
*
* 任务延时
* 参数: 延时的毫秒数
*
******************************************************************************/
void TWDelay( u16 ms )
{
u16 i;
TW_TCB *loc_tcb;
for(i=0; i<16; i++)
{
if (pTaskTCB[i] == pCurrent)
{
loc_tcb = pCurrent;
disable();
loc_tcb->Ticks = ms/2; // 填入延时数
pTaskTCB[i] = (TW_TCB*)loc_tcb->Next; // 摘除此任务
loc_tcb->Next = (void*)pSpdTCB[i]; // 放入等待任务表
pSpdTCB[i] = loc_tcb;
enable();
break;
}
}
TWSched(); // 调度
TWContext(); // 任务上下文切换
}
/******************************************************************************
*
* 强行唤醒一个任务
* 参数: 要唤醒的任务的任务控制板
*
******************************************************************************/
void TWWakeUp( TW_TCB *tcb )
{
u16 i;
TW_TCB *loc_tcb, *loc_tcb1;
for(i=0; i<16; i++)
{
loc_tcb = pSpdTCB[i];
loc_tcb1 = loc_tcb;
while(loc_tcb != (TW_TCB*)0)
{
if (loc_tcb == tcb) // 找到此任务
{
tcb->Ticks = 0; // 强行结束挂起状态
if (loc_tcb != loc_tcb1) // 从挂起表内摘除该就绪任务
{
loc_tcb1->Next = loc_tcb->Next;
}
else
{
pSpdTCB[i] = (TW_TCB*)loc_tcb->Next;
}
loc_tcb->Next = (void*)0; // 断尾
if (pTaskTCB[i] == (TW_TCB*)0) // 放该任务于就绪表的尾部
{
pTaskTCB[i] = loc_tcb;
}
else
{
loc_tcb1 = pTaskTCB[i];
while(loc_tcb1->Next != (TW_TCB*)0)
{
loc_tcb1 = (TW_TCB*)loc_tcb1->Next;
}
loc_tcb1->Next = (void*)loc_tcb;
}
TWSched(); // 调度
TWContext(); // 任务上下文切换
return;
}
loc_tcb1 = loc_tcb;
loc_tcb = (TW_TCB*)loc_tcb1->Next;
} // 遍历所有任务,对任务时间进行管理
}
}
void TWIdelTask( void )
{
TWIdelTick = 0;
for(;;)
{
disable();
TWIdelTick ++;
enable();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -