📄 cpu.h
字号:
__asm__ __volatile__("RJMP Int_OSSched \
\t"); //重新调度
}
}
////////////////////////////////////////////任务处理
/*******************************************************
** 函数名: OSTaskSuspend()
** 子函数: OSSched();
** 输 入: prio 要挂起的任务ID
** 输 出: 无
** 功 能: 挂起任务,即从任务就绪表上去除标志位
--------------------------------------------------------
*******************************************************/
void OSTaskSuspend(unsigned char prio)
{
TCB[prio].OSWaitTick=0;
OSRdyTbl &= ~(0x01<<prio); //从任务就绪表上去除标志位
if(OSTaskRunningPrio==prio) //当要挂起的任务为当前任务
OSSched(); //从新调度
}
/*******************************************************
** 函数名: OSTaskResume()
** 子函数: OSSched();
** 输 入: prio 要恢复的任务ID
** 输 出: 无
** 功 能: 恢复任务 可以让被OSTaskSuspend或 OSTimeDly暂停的任务恢复
--------------------------------------------------------
*******************************************************/
//
void OSTaskResume(unsigned char prio)
{
OSRdyTbl |= 0x01<<prio; //从任务就绪表上重置标志位
TCB[prio].OSWaitTick=0; //将时间计时设为0,到时
if(OSTaskRunningPrio>prio) //当要当前任务的优先级低于重置位的任务的优先级
OSSched(); //从新调度
}
/*******************************************************
** 函数名: OSTimeDly()
** 子函数: OSSched();
** 输 入: ticks 延迟的时钟节拍数
** 输 出: 无
** 功 能: 任务延时
--------------------------------------------------------
*******************************************************/
void OSTimeDly(unsigned int ticks)
{
if(ticks) //当延时有效,即ticks!=0
{
OSRdyTbl &= ~(0x01<<OSTaskRunningPrio); //清就绪标志
TCB[OSTaskRunningPrio].OSWaitTick=ticks;//赋时钟节拍数
OSSched(); //从新调度
}
}
/***********************
** 信号量 **
***********************/
struct SemBlk
{
unsigned char OSEventType; //型号 0,信号量独占型;1信号量共享型
unsigned char OSEventState; //状态 0,不可用;1,可用
unsigned char OSTaskPendTbl; //等待信号量的任务列表
} Sem[10];
/*******************************************************
** 函数名: OSSemCreat()
** 子函数: 无
** 输 入: Index任务ID Type信号量类型
** 输 出: 无
** 功 能: 初始化信号量
--------------------------------------------------------
*******************************************************/
void OSSemCreat(unsigned char Index,unsigned char Type)
{
Sem[Index].OSEventType=Type; //型号 0,信号量独占型;1信号量共享型
Sem[Index].OSTaskPendTbl=0;
Sem[Index].OSEventState=0;
}
/***********************************************************************
** 函数名: OSTaskSemPend()
** 子函数: 无
** 输 入: Index任务ID Timeout等待时间
** 输 出: 无
** 功 能: 任务等待信号量,挂起 当Timeout==0xffff时,为无限延时
------------------------------------------------------------------------
************************************************************************/
unsigned char OSTaskSemPend(unsigned char Index,unsigned int Timeout)
{
//unsigned char i=0;
if(Sem[Index].OSEventState) //信号量有效
{
if(Sem[Index].OSEventType==0) //如果为独占型
Sem[Index].OSEventState = 0x00; //信号量被独占,不可用
}
else
{ //加入信号的任务等待表
Sem[Index].OSTaskPendTbl |= 0x01<<OSTaskRunningPrio;
TCB[OSTaskRunningPrio].OSWaitTick=Timeout; //如延时为0,刚无限等待
OSRdyTbl &= ~(0x01<<OSTaskRunningPrio); //从任务就绪表中去除
OSSched(); //从新调度
if(TCB[OSTaskRunningPrio].OSWaitTick==0 ) //超时,未能拿到资源
return 0;
}
return 1;
}
/***********************************************************************
** 函数名: OSSemPost()
** 子函数: 无
** 输 入: Index任务ID
** 输 出: 无
** 功 能: 发送一个信号量,可以从任务或中断发送
------------------------------------------------------------------------
************************************************************************/
void OSSemPost(unsigned char Index)
{
if(Sem[Index].OSEventType) //当要求的信号量是共享型
{
Sem[Index].OSEventState=0x01; //使信号量有效
OSRdyTbl |=Sem [Index].OSTaskPendTbl; //使在等待该信号的所有任务就绪
Sem[Index].OSTaskPendTbl=0; //清空所有等待该信号的等待任务
}
else //当要求的信号量为独占型
{
unsigned char i;
for (i = 0; i < OS_TASKS && !(Sem[Index].OSTaskPendTbl & (0x01<<i)); i++);
if(i < OS_TASKS) //如果有任务需要
{
Sem[Index].OSTaskPendTbl &= ~(0x01<<i);//从等待表中去除
OSRdyTbl |= 0x01<<i; //任务就绪
}
else
{
Sem[Index].OSEventState =1; //使信号量有效
}
}
}
/***********************************************************************
** 函数名: OSTaskSemPost()
** 子函数: 无
** 输 入: Index任务ID
** 输 出: 无
** 功 能: 从任务发送一个信号量,并进行调度
------------------------------------------------------------------------
************************************************************************/
void OSTaskSemPost(unsigned char Index)
{
OSSemPost(Index);
OSSched();
}
//
//
/***********************************************************************
** 函数名: OSSemClean()
** 子函数: 无
** 输 入: Index任务ID
** 输 出: 无
** 功 能: 清除一个信号量,只对共享型的有用。
** 对于独占型的信号量,在任务占用后,就交得不可以用了。
------------------------------------------------------------------------
************************************************************************/
void OSSemClean(unsigned char Index)
{
Sem[Index].OSEventState =0; //要求的信号量无效
}
/***********************************************
** 函数名: TCN0Init
** 功 能: 初始化定时器0作为时钟节拍 5ms
** 输 入: 无
** 输 出: 无
------------------------------------------------
***********************************************/
void TCN0Init(void) // 计时器0
{
TCCR0 = 0;
TCCR0 |= (1<<CS02); // 256预分频
TIMSK |= (1<<TOIE0); // T0溢出中断允许
TCNT0 = 100; // 置计数起始值
}
/***********************************************
** 函数名: SIGNAL
** 功 能: 时钟节拍中断 5ms
** 输 入: 无
** 输 出: 无
------------------------------------------------
***********************************************/
SIGNAL(SIG_OVERFLOW0)
{
IntNum++; //中断嵌套+1
sei(); //在中断中,重开中断
unsigned char i;
for(i=0;i<OS_TASKS;i++) //任务时钟
{
if(TCB[i].OSWaitTick && TCB[i].OSWaitTick!=0xffff)
{
TCB[i].OSWaitTick--;
if(TCB[i].OSWaitTick==0) //当任务时钟到时,必须是由定时器减时的才行
{
OSRdyTbl |= (0x01<<i); //使任务可以重新运行
OSCoreState|=0x02; //要求任务切换的标志位
}
}
}
TCNT0=100;
cli();
IntNum--; //中断嵌套-1
IntSwitch(); //进行任务调度
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -