?? core.c
字號:
/***********************************************************
* miRTOS是一個可在avr上運行的mini RTOS,它屬于自由軟件,在
*它只實現(xiàn)了簡單的任務(wù)切換、任務(wù)之間的消息傳遞、任務(wù)的停止與
*繼續(xù)等功能,如果你有興趣,可以在這個基礎(chǔ)上增加信號量、郵箱
*等各種功能。
* 2006年元旦閑著沒事,就寫了這個RTOS,希望能給想了解RTOS
*的人一些幫助,其實單片機上的RTOS沒多少神秘,它通過對各個任
*務(wù)的上下文切換,來實現(xiàn)任務(wù)的分時運行。外加上信號量,消息等
*輔助功能。
* 你可以在miRTOS上做任何操作,比如修改、增加功能等。但請
*在修改的地方加上相應(yīng)的修改記錄,實現(xiàn)的功能,并將其公開化。
*如果可能的話,請發(fā)一份修改后的副本給我(^_^)。
* 如果你有疑問,可以找我,我的郵箱: frankie.hu@gmail.com
*當然你也可以到www.ouravr.com 的論壇上找hunter0773,希望我們
*能共同進步。
* 另外,在AVR上我只是一個菜鳥,希望不要被老鳥門歧視哦。呵呵。
*frankie.hu 寫于 2006.01.05夜。
* 在你修改或轉(zhuǎn)載時,請不要刪除上面的聲名信息。
***********************************************************/
#include "core.h"
#include "os_asm.h"
#include "intrinsics.h"
typedef struct _os_tcb{
INT8U *Stack; /* 任務(wù)堆棧指針 */
INT8U Message; /* 任務(wù)消息 */
INT8U TimeTick; /* 延時時間 */
INT8U Status; /* 任務(wù)狀態(tài) */
} OS_TCB;
INT8U FREE_TASK_STACK[FREE_TASK_STACK_LEN];
OS_TCB os_tcb[TASK_CNT+1],*Current_TCB;
/*
***********************************************************
*函 數(shù) 名: OS_DecTick
*功 能: 任務(wù)延時時間片處理
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 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++;
}
}
/*
***********************************************************
*函 數(shù) 名: OS_SetHighRdy
*功 能: 設(shè)置優(yōu)先級最高且裝備就緒的任務(wù)為當前任務(wù)
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
__task void OS_SetHighRdy(void)
{
INT8U i;
OS_TCB *TcbTmp;
if(!(Current_TCB->Status&TS_LOCK)) //檢測當前任務(wù)是否被鎖定
{ //當前任務(wù)沒有被鎖定
TcbTmp = os_tcb;
for(i=TASK_CNT+1;i>0;i--)
{
if(TcbTmp->Status == 0)
{
Current_TCB = TcbTmp;
return;
}
TcbTmp++;
}
}
}
/*
***********************************************************
*函 數(shù) 名: OS_FreeTask
*功 能: OS空閑任務(wù)
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_FreeTask(void)
{
while(1)
{
OS_Scheduler();
}
}
/*
***********************************************************
*函 數(shù) 名: OS_CreateTask
*功 能: 創(chuàng)建任務(wù)
*輸入?yún)?shù): entry :任務(wù)入口 StackTop :堆棧頂
* Priority : 任務(wù)的優(yōu)先級
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 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; /* 任務(wù)置為就緒狀態(tài) */
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;
}
/*
***********************************************************
*函 數(shù) 名: OS_DelayTick
*功 能: 當前任務(wù)延時
*輸入?yún)?shù): DlyTick : 要延時的時間片
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 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(); //任務(wù)切換
}
}
/*
***********************************************************
*函 數(shù) 名: OS_Tasksuspend
*功 能: 將優(yōu)先級為 Priority 的任務(wù)置為懸掛狀態(tài)
*輸入?yún)?shù): 要懸掛的任務(wù)的優(yōu)先級
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_TaskSuspend(INT8U Priority)
{
OS_TCB *TcbTmp;
if (Priority < TASK_CNT) //檢測任務(wù)優(yōu)先級是否有效
{
TcbTmp = &os_tcb[Priority];
IntEnter();
TcbTmp->Status |= TS_SUSPEND;
IntLeave();
if(Current_TCB == TcbTmp)
OS_Scheduler();
}
}
/*
***********************************************************
*函 數(shù) 名: OS_TaskResume
*功 能: 喚醒優(yōu)先級為 Priority 的任務(wù)
*輸入?yún)?shù): Priority 要喚醒的任務(wù)的優(yōu)先級
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_TaskResume(INT8U Priority)
{
OS_TCB *TcbTmp;
if (Priority < TASK_CNT) //檢測任務(wù)優(yōu)先級是否有效
{
TcbTmp = &os_tcb[Priority];
IntEnter();
TcbTmp->Status &= ~TS_SUSPEND;
IntLeave();
}
}
/*
***********************************************************
*函 數(shù) 名: OS_SendMessage
*功 能: 向優(yōu)先級為 Priority 的任務(wù)傳遞消息 Message
*輸入?yún)?shù): Priority 任務(wù)的優(yōu)先級 Message 要傳遞的消息
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_SendMessage(INT8U Priority,INT8U Message)
{
OS_TCB *TcbTmp;
if (Priority < TASK_CNT) //檢測任務(wù)優(yōu)先級是否有效
{
TcbTmp = &os_tcb[Priority];
IntEnter();
TcbTmp->Message = Message;
TcbTmp->Status &= ~TS_MESSAGE;
IntLeave();
}
}
/*
***********************************************************
*函 數(shù) 名: OS_WaitMessage
*功 能: 等待消息
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 接收到的消息
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
INT8U OS_WaitMessage(void)
{
IntEnter();
Current_TCB->Status |= TS_MESSAGE; //置當前任務(wù)為等待任務(wù)狀態(tài)
IntLeave();
OS_Scheduler(); //任務(wù)切換,等待消息
return Current_TCB->Message;
}
/*
***********************************************************
*函 數(shù) 名: OS_TaskLock
*功 能: 將當前任務(wù)鎖定,不再作任務(wù)調(diào)度
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_TaskLock(void)
{
IntEnter();
Current_TCB->Status |= TS_LOCK;
IntLeave();
}
/*
***********************************************************
*函 數(shù) 名: OS_TaskUnlock
*功 能: 將當前任務(wù)解鎖,恢復(fù)任務(wù)調(diào)度
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_TaskUnlock(void)
{
IntEnter();
Current_TCB->Status &= ~TS_LOCK;
IntLeave();
}
/*
***********************************************************
*函 數(shù) 名: OS_Init
*功 能: 初始化系統(tǒng)
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_Init(void)
{
/* 設(shè)置定時器 */
//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; //啟動定時器
/* 創(chuàng)建空閑任務(wù) */
OS_CreateTask(OS_FreeTask,FREE_TASK_STACK+FREE_TASK_STACK_LEN,TASK_CNT);
Current_TCB = &os_tcb[TASK_CNT];
}
/*
***********************************************************
*函 數(shù) 名: OS_Start
*功 能: 啟動系統(tǒng)OS
*輸入?yún)?shù): 無
*輸出參數(shù): 無
*返 回 值: 無
*==========================================================
*日 期: 2006.01.01
*作 者: frankie.hu
*修改記錄:
***********************************************************
*/
void OS_Start(void)
{
__enable_interrupt();
StartTaskRunning(Current_TCB->Stack);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -