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

📄 tinyworks.c

📁 TinyWorks操作系统。 每个任务占6~10个字节的RAM空间
💻 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 + -