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