搜索
bottom↓
回复: 19

对于想用OS但又觉得单片机资源太过紧张,状态机是个不错的选择---分享一种状态机设计

[复制链接]

出0入0汤圆

发表于 2007-8-22 16:45:38 | 显示全部楼层 |阅读模式
如何利用有限状态机实现多任务



墨鱼



许多嵌入式应用领域,软件都是基于输入响应的组织方式,也叫反应式系统。把输入

信息进行归类有:离散的事件(如二值开关信号)、可以表示某个外部信号引发的中断或者例如发生了定时器溢出等。而数值信号则用于传递例如一次A/D采样的结果。有限状态机正是利用了这些输入的事件做为状态变更的依据,每一种状态对应执行一组操作。

(个人观点)所以这种方式最好是执行在一个由中断建立起来的硬件环境。例如键盘的输入是与中断相结和的,所以会有周立公的ZLG7290芯片(当然7290并不是因为这样才产生的)。这样就可充分利用这种机制而不必频繁的执行扫描。

不过由于需要根据输入的事件做相应的状态转换,使利用状态机进行软件的设计和编码带来的额外的负担。系统的复杂程度直接影响了设计人员对软件的理解和组织。借助有效的状态机设计工具可以降低设计人员的负担。

根据多任务操作系统的分类有协作型(也叫任务轮循),一个任务一直运行,直到该任主动放弃CPU,调度器安排另外一个任务运行。相应的在没有调度器的情况下,我们可以把对状态机的调用过程依次安排在一个超循环里。

       While( 1 ){

              //调用状态机1,处理事件1。

              StateMachine_NO_1( );

              //调用状态机2,处理事件2。

              StateMachine_NO_1( );

              。。。。。。。。。。。。。。。。。。。

               。。。。。。。。。。。。。。

             //状态机n

             StateMachine_NO_n( );

     }

各状态机在设计的时候必须保证不会出现死循环,长时间等待某一事件。例如以往的前后台方式等待定时器溢出使用的方法是不断查询标志位直到溢出为止,此时应该改为首先打开定时器,然后切换状态进入查询是否溢出,未溢出立即退出,转而执行其它状态机。待下一次执行到该状态机时由于状态仍处在查询定时溢出的状态之下,如果此时查询结果是定时器溢出将切换到另一种状态执行相应操作。

StateMachine_NO_1(void ){

       Static uint8 sm_no1_state  =  0;        //用于存放状态机当前状态的值

        。。。。。。。。。。。。。。。。。。。。。。。。。;         //其它变量。



       If( sm_no1_state  = =  0){//状态机等于‘0’吗?

             //执行操作,例如执行点亮一个LED 500mS

           。。。。。。。。。。。。。。。。。。。。。。。。。。

             //执行完打开LED操作后切换状态进入查询500ms时间到否

           sm_no1_state  =  1;

          //并打开定时器计数,500ms

         Star_Timer0_Delay_Ms(500);

      }



       If( sm_no1_state  = = 1){ //状态机等于‘1’吗?

              //判断定时器是否溢出。

              If( Rt_Timer0_full( ) = = 1){//每次只查询一次

              //定时器溢出,关闭定时器,关闭LED

               。。。。。。。。。。。。。。。。。。

             //同时切换状态

            sm_no1_state  =  2;

              //再次打开定时器

              Star_Timer0_Delay_Ms(500);

            }

             else ;//定时器未溢出保持当前状态退出,转而执行其它状态机。

      }



        If( sm_no1_state = = 2){ //状态机等于‘2’吗?

              If( Rt_Timer0_full( ) = = 1){

                     //定时器溢出,关闭定时器

                。。。。。。。。。。。。。。。。。。

              //同时切换状态

               sm_no1_state  =  0;

        }

         else ;//定时器未溢出保持当前状态退出,转而执行其它状态机。



     }



      Return ; //状态机1执行返回主循环。

}



如上所示状态机’1’执行了一个每隔1S点亮和关闭LED的任务。

类似的只要合理设计每个状态机所等待和处理的事件,就可实现多任务的并发执行。解决的状态机的原理后还需要考虑各状态机之间的资源共享和同步问题。

除状态机轮循这种简单的利用等待事件发生的空闲时间处理并发执行外还有基于事件优先级等等组织方式。不过由于过于复杂,大家可以借助于UML实时系统建模生成的框架,设计一个并发执行的软件只需要设计好状态图,当然实际实行起来UML过于抽象。

补充:状态机在执行状态切换时要执行入口操作和退出操作。

相对于使用RTOS的优点是对硬件的资源消耗较少特别是SRAM,但各状态机所使用的变量生存期需要根据实际好好斟酌。相比于前后台方式会有大量的静态变量。动态分配的变量仍然只存在于可重入函数中作临时审请的变量。

另外UML也支持RTOS,我想RTOS+状态机的开发方式再复杂的项目也能轻松应对了。

由于表达能力的不足无法很好的诠释状态机的更多优点和特性。而其缺点和应该注意的地方我想大家在往后的应用中会有很好的体会。过于复杂的项目如果没有掌握好状态机的设计工具建议不要选择这种方式,很可能会导致项目失败。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2007-8-22 17:38:39 | 显示全部楼层
在某些程序我也是这样做的

出0入0汤圆

发表于 2007-8-22 17:52:45 | 显示全部楼层
用usmartx,不用给任务单独分配堆栈。

占用sram少,1K的SRAM跑的很好。

512字节SRAM都可以。

出0入0汤圆

发表于 2007-8-22 19:57:04 | 显示全部楼层
谢谢  虽然还不太理解状态机的精髓 但感觉确实是很有用的东西

出0入0汤圆

发表于 2009-4-18 11:17:36 | 显示全部楼层
mark

出0入4汤圆

发表于 2009-4-18 12:37:18 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-8-12 19:24:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-6 10:51:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-6 11:57:35 | 显示全部楼层
现在还在于表面东西的学习。。。。看不太懂。。。。来一个具体的程序就好了~从main开始调用子函数什么的~

出0入16汤圆

发表于 2011-9-6 23:23:57 | 显示全部楼层
睡前记号 明天下班再看

出0入0汤圆

发表于 2011-9-7 00:37:16 | 显示全部楼层
有时间细看 mark

出0入0汤圆

发表于 2012-2-27 16:55:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-6-1 10:31:34 | 显示全部楼层
MAKE  楼主哪能稍微再详细点不

出0入0汤圆

发表于 2012-6-1 14:04:19 来自手机 | 显示全部楼层
学习学习,謝謝

出0入0汤圆

发表于 2012-6-27 09:08:08 | 显示全部楼层

学习学习,謝謝

出0入0汤圆

发表于 2012-6-27 14:14:52 | 显示全部楼层
最近在一个项目中使用了消息队列加状态机的方式,中断负责发出触发事件,状态机在主while循环中根据事件进行状态转换和动作输出。状态机是用状态转换表实现的,本来想用VisualState的(新版本没破解,就先放下了)。还没完成,过程略有坎坷。

出0入0汤圆

发表于 2012-6-27 19:57:32 | 显示全部楼层
mark!!!!

出0入0汤圆

发表于 2012-6-27 20:08:23 | 显示全部楼层
mark 虽然不是很懂 慢慢研究

出0入0汤圆

发表于 2013-7-13 16:39:55 | 显示全部楼层
mark      

出0入0汤圆

发表于 2013-7-13 19:10:35 来自手机 | 显示全部楼层
还没有领悟到起中的精髓!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 01:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表