shaw 发表于 2011-3-11 10:45:47

基于队列状态机的生产者消费者模型(QSM-PC)下位机移植

用了一段时间的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;
                }
}

/***********************************************************
*   函数名称:                                 
*   功能描述:系统初始化                                 
*   参数列表:                                          
*   返回结果:                                             
***********************************************************/
voidSystemInit(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) (原文件名:QSM_PC.rar)

flor 发表于 2011-3-11 10:59:22

不明白

shaw 发表于 2011-3-11 11:15:23

回复【1楼】flor
-----------------------------------------------------------------------

下载程序看看试试

jrcsh 发表于 2011-3-11 11:26:33

名字绕口

knight_avr 发表于 2011-3-11 11:32:04

TI的z-stack 就是用这样的系统 感觉的在8位机里面 最适合用了

Gorgon_Meducer 发表于 2011-3-11 13:17:46

好东西,赞一个。事件驱动的。

maimaige 发表于 2012-10-29 16:26:19

MARk 一下

gdgly 发表于 2013-3-6 09:29:29

这个不错!

igoal 发表于 2013-3-6 09:58:23

这种模式如果用于实时性要求很高的场合,估计不行,主循环轮询的时间是不定的,所以有可能不能及时处理中断.

Hz01800475 发表于 2013-5-10 18:28:19

基于队列状态机的生产者消费者模型{:lol:}

guew 发表于 2013-5-11 20:13:14

好东西,谢谢楼主无私分享!

zjsx133 发表于 2013-5-11 20:55:56

好东东,mark 下

Hz01800475 发表于 2013-6-5 18:02:56

基于队列状态机的生产者消费者模型

rossih 发表于 2013-6-5 18:11:03

学习!!
页: [1]
查看完整版本: 基于队列状态机的生产者消费者模型(QSM-PC)下位机移植