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

📄 core.c

📁 牛人写的AVR单片机操作系统源代码
💻 C
字号:
/***********************************************************
*    miRTOS是一个可在avr上运行的mini RTOS,它属于自由软件,在
*它只实现了简单的任务切换、任务之间的消息传递、任务的停止与
*继续等功能,如果你有兴趣,可以在这个基础上增加信号量、邮箱
*等各种功能。
*    2006年元旦闲着没事,就写了这个RTOS,希望能给想了解RTOS
*的人一些帮助,其实单片机上的RTOS没多少神秘,它通过对各个任
*务的上下文切换,来实现任务的分时运行。外加上信号量,消息等
*辅助功能。
*    你可以在miRTOS上做任何操作,比如修改、增加功能等。但请
*在修改的地方加上相应的修改记录,实现的功能,并将其公开化。
*如果可能的话,请发一份修改后的副本给我(^_^)。
*    如果你有疑问,可以找我,我的邮箱: frankie.hu@gmail.com
*当然你也可以到www.ouravr.com 的论坛上找hunter0773,希望我们
*能共同进步。
*  另外,在AVR上我只是一个菜鸟,希望不要被老鸟门歧视哦。呵呵。
*frankie.hu 写于 2006.01.05夜。
*    在你修改或转载时,请不要删除上面的声名信息。
***********************************************************/

#include "core.h"
#include "os_asm.h"
#include "intrinsics.h"

typedef struct _os_tcb{
    INT8U   *Stack;             /* 任务堆栈指针 */
    INT8U  Message;            /* 任务消息 */
    INT8U  TimeTick;           /* 延时时间 */
    INT8U   Status;             /* 任务状态 */
} OS_TCB;


INT8U FREE_TASK_STACK[FREE_TASK_STACK_LEN];
OS_TCB  os_tcb[TASK_CNT+1],*Current_TCB;


/*
***********************************************************
*函 数 名:  OS_DecTick
*功    能:  任务延时时间片处理
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/

__task void OS_DecTick(void)
{
    INT8U i;
    OS_TCB *TcbTmp;

    TcbTmp = os_tcb;
    for(i=0;i<TASK_CNT;i++)
    {
        if(TcbTmp->TimeTick)
        {
            TcbTmp->TimeTick--;
        }
        if(!TcbTmp->TimeTick)
            TcbTmp->Status &= ~TS_DELAY;
        TcbTmp++;
    }
}

/*
***********************************************************
*函 数 名:  OS_SetHighRdy
*功    能:  设置优先级最高且装备就绪的任务为当前任务
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
__task void OS_SetHighRdy(void)
{
    INT8U i;
    OS_TCB *TcbTmp;
    if(!(Current_TCB->Status&TS_LOCK))  //检测当前任务是否被锁定
    {                               //当前任务没有被锁定
        TcbTmp = os_tcb;
        for(i=TASK_CNT+1;i>0;i--)
        {
            if(TcbTmp->Status == 0)
            {
                Current_TCB = TcbTmp;
                return;
            }
            TcbTmp++;
        }
    }

}
/*
***********************************************************
*函 数 名:  OS_FreeTask
*功    能:  OS空闲任务
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_FreeTask(void)
{
    while(1)
    {
        OS_Scheduler();
    }
}

/*
***********************************************************
*函 数 名:  OS_CreateTask
*功    能:  创建任务
*输入参数:  entry :任务入口 StackTop :堆栈顶
*           Priority : 任务的优先级
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_CreateTask(void(* entry)(void),INT8U *StackTop,INT8U priority)
{
    OS_TCB  *TcbTmp;
    INT8U   *STACK;
    INT8U   i;

    TcbTmp = &os_tcb[priority];
    TcbTmp->Status = 0x00;//TS_READY;       /* 任务置为就绪状态 */
    TcbTmp->Message = 0x00;
    TcbTmp->TimeTick = 0x00;

    STACK = StackTop - (Function_Nest_Depth)*2;

    *(--StackTop) = (INT8U)((INT16U)entry);
    *(--StackTop) = (INT8U)((INT16U)entry>>8);
    --StackTop;
    for(i=0;i<30;i++)   //set R0..R27,R30,R31 with 0
        *(--STACK) = 0;

    *(--STACK) = 0x80;    //Set SREG Global interrupt enable
    *(--STACK) = (INT8U)((INT16U)StackTop);
    *(--STACK) = (INT8U)((INT16U)StackTop>>8);

    TcbTmp->Stack = STACK;
}
/*
***********************************************************
*函 数 名:  OS_DelayTick
*功    能:  当前任务延时
*输入参数:  DlyTick : 要延时的时间片
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_DelayTick(INT8U DlyTick)
{
    if(DlyTick)
    {
        IntEnter();       //禁止中断使能
        Current_TCB->TimeTick = DlyTick;
        Current_TCB->Status |= TS_DELAY;
        IntLeave();       //中断使能
        OS_Scheduler();   //任务切换
    }
}

/*
***********************************************************
*函 数 名:  OS_Tasksuspend
*功    能:  将优先级为 Priority 的任务置为悬挂状态
*输入参数:  要悬挂的任务的优先级
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_TaskSuspend(INT8U Priority)
{
    OS_TCB *TcbTmp;

    if (Priority < TASK_CNT)    //检测任务优先级是否有效
    {
        TcbTmp = &os_tcb[Priority];
        IntEnter();
        TcbTmp->Status |= TS_SUSPEND;
        IntLeave();
        if(Current_TCB == TcbTmp)
            OS_Scheduler();
    }
}
/*
***********************************************************
*函 数 名:  OS_TaskResume
*功    能:  唤醒优先级为 Priority 的任务
*输入参数:  Priority 要唤醒的任务的优先级
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_TaskResume(INT8U Priority)
{
    OS_TCB *TcbTmp;

    if (Priority < TASK_CNT)    //检测任务优先级是否有效
    {
        TcbTmp = &os_tcb[Priority];
        IntEnter();
        TcbTmp->Status &= ~TS_SUSPEND;
        IntLeave();
    }
}
/*
***********************************************************
*函 数 名:  OS_SendMessage
*功    能:  向优先级为 Priority 的任务传递消息 Message
*输入参数:  Priority 任务的优先级 Message 要传递的消息
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_SendMessage(INT8U Priority,INT8U Message)
{
    OS_TCB *TcbTmp;

    if (Priority < TASK_CNT)    //检测任务优先级是否有效
    {
        TcbTmp = &os_tcb[Priority];
        IntEnter();
        TcbTmp->Message = Message;
        TcbTmp->Status &= ~TS_MESSAGE;
        IntLeave();
    }
}
/*
***********************************************************
*函 数 名:  OS_WaitMessage
*功    能:  等待消息
*输入参数:  无
*输出参数:  无
*返 回 值:  接收到的消息
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
INT8U OS_WaitMessage(void)
{
    IntEnter();
    Current_TCB->Status |= TS_MESSAGE;  //置当前任务为等待任务状态
    IntLeave();
    OS_Scheduler();         //任务切换,等待消息
    return Current_TCB->Message;
}
/*
***********************************************************
*函 数 名:  OS_TaskLock
*功    能:  将当前任务锁定,不再作任务调度
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_TaskLock(void)
{
    IntEnter();
    Current_TCB->Status |= TS_LOCK;
    IntLeave();
}
/*
***********************************************************
*函 数 名:  OS_TaskUnlock
*功    能:  将当前任务解锁,恢复任务调度
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_TaskUnlock(void)
{
    IntEnter();
    Current_TCB->Status &= ~TS_LOCK;
    IntLeave();
}
/*
***********************************************************
*函 数 名:  OS_Init
*功    能:  初始化系统
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_Init(void)
{
    /* 设置定时器 */
    //TCCR0 = 0x00; //stop timer
    //TCNT0 = TCNT0_RELOAD_VALUE; //set count value
    //TCCR0 = 0x04; //start timer

    TCCR0  = 0x00;//停止定时器
    //TCNT0  = 0x00;//初始值
    OCR0   = TCNT0_RELOAD_VALUE;//匹配值
    TIMSK |= (1<<OCIE0);	//中断允许
    TCCR0  = TCCR0_VALUE;	//启动定时器
    /* 创建空闲任务 */
    OS_CreateTask(OS_FreeTask,FREE_TASK_STACK+FREE_TASK_STACK_LEN,TASK_CNT);
    Current_TCB = &os_tcb[TASK_CNT];
}

/*
***********************************************************
*函 数 名:  OS_Start
*功    能:  启动系统OS
*输入参数:  无
*输出参数:  无
*返 回 值:  无
*==========================================================
*日    期:  2006.01.01
*作    者:  frankie.hu
*修改记录:
***********************************************************
*/
void OS_Start(void)
{
    __enable_interrupt();
    StartTaskRunning(Current_TCB->Stack);
}



⌨️ 快捷键说明

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