/*****************************************************************************************
* YeSRTOS/YeSRTOS.c
*
* 核心文件
*
* Copyright (C) 2009 叶少明
*
* 2009-8-10 YeSRTOS atMega16 版本
*
* 占先式内核 提供系统延时 挂起 恢复 信号量等功能 最大任务量8个
*****************************************************************************************/
#include "YeSRTOS.h"
/******************全局变量定义***************/
INT8U StackIdle[StackSizeIdle]; // 建立空闲任务栈
INT8U OSRdyTbl; // 就绪任务列表
INT8U OSPrioCur; // 当前任务的优先级
INT8U OSPrioHighRdy; // 即将要运行任务的优先级
INT32U IdleCount; // 空闲任务自加数
struct TaskCtrBlock TCB[OS_TASKS + 1]; // 定义任务控制块TCB数组
INT16U *TEMP_SP;
/*
+---------------------------------------------------------------------------------------+
|函数名称: OSSetPrioRdy |
|---------------------------------------------------------------------------------------|
|函数原型: void OSSetPrioRdy(prio) |
| |
|函数功能: 任务就绪 |
| |
|入口参数: prio 任务优先级 |
+---------------------------------------------------------------------------------------+
*/
#define OSSetPrioRdy(prio) \
{ \
OSRdyTbl |= 0x01<<prio; \
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: OSDelPrioRdy |
|---------------------------------------------------------------------------------------|
|函数原型: void OSDelPrioRdy(prio) |
| |
|函数功能: 任务删除 |
| |
|入口参数: prio 任务优先级 |
+---------------------------------------------------------------------------------------+
*/
#define OSDelPrioRdy(prio) \
{ \
OSRdyTbl &= ~(0x01<<prio); \
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: SPPoint |
|---------------------------------------------------------------------------------------|
|函数原型: void SPPoint(prio) |
| |
|函数功能: 处理C与汇编中SP指向问题 |
+---------------------------------------------------------------------------------------+
*/
void SPPoint(void)
{
TEMP_SP=&(TCB[OSPrioCur].OSTCBStkPtr);
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: YeS_TaskCreate |
|---------------------------------------------------------------------------------------|
|函数原型: void YeS_TaskCreate(void (*Task)(void),INT8U *Stack,INT8U t_Prio) |
| |
|函数功能: 建立任务 |
| |
|入口参数: *Task:任务函数地址;*Stack:任务栈顶指针;t_Prio:任务优先级 |
+---------------------------------------------------------------------------------------+
*/
void YeS_TaskCreate(void (*Task)(void),INT8U *p_Stack,INT8U t_Prio)
{
unsigned char i=0;
if(t_Prio <= OS_TASKS)
{
*(p_Stack--) = (unsigned char)((unsigned int)Task&0x00ff);; //函数入口
*(p_Stack--) = (unsigned char)(((unsigned int)Task&0xff00)>>8); //函数入口
*(p_Stack--) =0x00; //R1 __zero_reg__
*(p_Stack--) =0x00; //R0 __tmp_reg__
*(p_Stack--) =0x80; //SREG 在任务中,开启全局中断
for(i=0;i<30;i++)
*(p_Stack--)=i;
TCB[t_Prio].OSTCBStkPtr = (INT16U)p_Stack; // 将人工堆栈的栈顶,保存到堆栈的数组中
TCB[t_Prio].OSTCBDly = 0; // 初始化任务延时
OSSetPrioRdy(t_Prio); // 在任务就绪表中登记
}
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: YeS_Start |
|---------------------------------------------------------------------------------------|
|函数原型: void YeS_Start(void) |
| |
|函数功能: 系统启动 |
| |
|入口参数: 无 |
+---------------------------------------------------------------------------------------+
*/
void YeS_Start(void)
{
OSPrioCur = OSPrioHighRdy=0; // 在就绪表中查找最高级的就绪任务
SP=TCB[OSPrioCur].OSTCBStkPtr+33; //将栈顶移到pc位置,准备弹出
TIMSK|=_BV(TOIE0);
sei(); //开系统总中断
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: YeS_TimeDelay |
|---------------------------------------------------------------------------------------|
|函数原型: void YeS_TimeDelay(INT16U ticks) |
| |
|函数功能: 任务延时 |
| |
|入口参数: 延时的时间,任务等待时钟节拍的个数 |
| |
|有关说明: 延时数不得超出INT16U的范围 |
+---------------------------------------------------------------------------------------+
*/
void YeS_TimeDelay(INT16U ticks)
{
INT8U i=0;
if(ticks > 0) // 当延时有效
{
OS_ENTER_CRITICAL();
OSDelPrioRdy(OSPrioCur); // 把任务从就绪表中删去
TCB[OSPrioCur].OSTCBDly = ticks; // 设置任务延时节拍数
OS_EXIT_CRITICAL();
for( i = 0;(i < OS_TASKS) && (!(OSRdyTbl & (0x01<<i)));i++ );//查找最高优先级算法
OSPrioHighRdy = i;
OSSched(); // 重新调度
}
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: YeS_TaskSuspend |
|---------------------------------------------------------------------------------------|
|函数原型: void YeS_TaskSuspend(INT8U prio) |
| |
|函数功能: 任务挂起 |
| |
|入口参数: 挂起任务的优先级 |
+---------------------------------------------------------------------------------------+
*/
void YeS_TaskSuspend(INT8U prio)
{
OS_ENTER_CRITICAL();
TCB[prio].OSTCBDly = 0;
OSDelPrioRdy(prio); // 从任务就绪表上去除标志位
OS_EXIT_CRITICAL();
if(OSPrioCur == prio) // 当要挂起的任务为当前任务
{
OSSched(); // 重新调度
}
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: YeS_TaskResume |
|---------------------------------------------------------------------------------------|
|函数原型: void YeS_TaskResume(INT8U prio) |
| |
|函数功能: 任务恢复 |
| |
|入口参数: 恢复任务的优先级 |
+---------------------------------------------------------------------------------------+
*/
void YeS_TaskResume(INT8U prio)
{
OS_ENTER_CRITICAL();
OSSetPrioRdy(prio); // 从任务就绪表上重置标志位
TCB[prio].OSTCBDly = 0; // 将时间计时设为0,延时到
OS_EXIT_CRITICAL();
if(OSPrioCur > prio) // 当前任务的优先级低于重置位的任务的优先级
{
OSSched(); // 重新调度
}
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: TickIntHook |
|---------------------------------------------------------------------------------------|
|函数原型: void TickIntHook(void) |
| |
|函数功能: T0中断钩子程序 |
| |
|有关说明: 用来为需要延时的任务进行计时 |
+-