用了一段时间的LabVIEW,发现一种叫QSM-PC(基于队列状态机的生产者消费者模型)特别实用、稳定,于是根据自己理解,将其移植到了下位机,欢迎大家讨论。。。。
/*===========================================================================
* 程序名称:
* 源文件名: QSM_PC.c
* 创建日期: 2011年3月
* 作 者: Shaw
* 网 站:
* 版本说明: v1.0
*---------------------------------------------------------------------------
* 硬件环境:
* Proteus仿真,ATmega128单片机,CPU时钟为内部1MHz
*---------------------------------------------------------------------------
* 软件环境:
* AVR studio 4.12 & WinAVR-2005,Proteus
*---------------------------------------------------------------------------
* 内容描述: 一个基于队列状态机和生产者消费者循环实现的简单调度器
* 生产者基于各种中断,可实现外部响应或者数据接收,在中断函数中只执行入队列操作
* 相应任务放到消费者循环中处理
* 消费者循环中实时查询队列中任务,然后顺序执行,非中断任务可自己添加,也可将其放入default中 *
*---------------------------------------------------------------------------
* 【版权】 Copyright(C) All Rights Reserved
* 【声明】 此程序用于测试,引用请注明版权和作者信息!
*===========================================================================*/
/********************
* 用枚举定义任务状态
********************/
enum
{
INIT_TASK,
TSAK_INTERRUPT0,
TSAK_USART0,
// 。。。。。 //其他任务常量
}TASK;
/***********************************************************
* 函数名称: Main()
* 功能描述: 主函数
* 参数列表:
* 返回结果:
***********************************************************/
int main(void)
{
CreateQueue(&fsmQueue, fsmBuffer, BUFFER_SIZE); //创建状态队列
EnqueueElement(&fsmQueue, INIT_TASK); //初始状态入队列
while (1)
{
CustomerLoop(); //消费者循环
}
}
/***********************************************************
* 函数名称:
* 功能描述: 消费者循环
* 当触发中断时,相应任务进入队列,不会出现遗漏现象
* 通过该循环实现对任务的处理,在默认任务中执行查询等操作
* 参数列表:
* 返回结果:
***********************************************************/
void CustomerLoop(void)
{
switch (DequeueElement(&fsmQueue)) //通过元素出队列实现状态机
{
case INIT_TASK:
SystemInit(); //系统初始化
break;
case TSAK_INTERRUPT0: //当触发外部中断0时,进入该状态
TaksInterrupt0();
break;
case TSAK_USART0: //当串口0中断触发时,进入该状态
//TaksUsart0();
break;
/*
case TSAK_OTHERS: //其他通过中断实现的操作
//TaksUsart0();
break;
...........
*/
default: //当没有中断触发时,进入查询状态(这里使用时间触发方式)或者直接进入低功耗模式
//TaksPool();
OS_Dispatch_Tasks();
//进入低功耗模式
break;
}
}
/***********************************************************
* 函数名称:
* 功能描述: 系统初始化
* 参数列表:
* 返回结果:
***********************************************************/
void SystemInit(void)
{
DDRB = 0xff;
Uart_Init(); //串口初始化
InterruptInit(); //中断初始化
//这里还调用了时间触发模式
OS_Init_T0();
OS_Add_Task(Usart0Trans, 0, 500, 0); // 无中断任务时,每隔500ms执行一次
OS_Start();//开中断
// sei();
// EnqueueElement(&fsmQueue, TSAK_USART0);
// EnqueueElement(&fsmQueue, TASK_POLL); //如果系统中需要用到查询方式,则在这里加入
}
/***********************************************************
* 函数名称:SIG_INTERRUPT0
* 功能描述:外部中断0
* 参数列表:
* 返回结果:
***********************************************************/
SIGNAL(SIG_INTERRUPT0)
{
EnqueueElement(&fsmQueue, TSAK_INTERRUPT0);
}
点击此处下载 ourdev_621646EV9B65.rar(文件大小:250K) (原文件名SM_PC.rar)
|