OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3151|回复: 5

新手问一个关于状态机简单问题,刚刚开始接触

[复制链接]

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
发表于 2016-6-24 17:10:06 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 东北小辉辉 于 2016-6-24 17:28 编辑

RT,小弟最近刚刚开始接触一些状态机和操作系统的书,有一个编程思路想来问一下大家。

我现在想实现一种时间触发的状态机调度模式,主函数打算用switch case来写,但是现在有一点想不通,就是如何处理一个运行时间比较长的任务?

举个例子,比如我现在的功能是用sim900发短信,这个应用,那么发短信之前,首先,发送AT指令,同步波特率,等待返回OK,然后发送ATE关闭回显,等待返回OK,之后还有设置文本模式等等,一直到最后把短信内容发送出去,这是一个完整的任务,假设运行时间为150ms,当然,程序语句的执行时间是很短的,主要时间浪费在了判断是否发送成功的那个OK上,假设这个接收到OK的时间是15ms,这里不能用while死等,因为我这里只有一个应用,我采用了休眠的方式,然后用一个时基定时器来唤醒。

这个任务我如何来进行状态划分?如果按照15ms的时间,分成case1到case10的话状态是不是太多了?如果某个任务需要运行1s的时候怎么办,难道要100个case,那样程序会很混乱,可读性也不好。

现在考虑的还是只有一个任务,不涉及和其他任务通信的功能,也不涉及外部到来的事件。

大致写一下程序的框架.

原本的顺序编程模式

void main( void )
{
    while( 1 )
    {
        发送AT
        等待接收OK
        发送ATE
        等待接收OK
        ...
        等待接收OK
        发送短信内容
    }
}

现在我考虑的模式

void main( void )
{
    while(1)
    {
        switch( state )
        {
            case 1:
            {
                发送AT
                休眠
                break;
            }
            case 2://时间到15ms
            {
                if( 接收到OK )
                {
                    发送ATE
                }
                else
                {
                    //发送失败
                    //异常处理
                }
                休眠
                break;
            }
            ...
            case 10://时间到150ms
            {
                if( 接收到OK )
                {
                    发送短信内容
                }
                else
                {
                    //发送失败
                    //异常处理
                }
                休眠
                break;
            }
        }
    }
}

定时器中断
{
    清中断
    state++;
}

半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2016-6-24 21:29:40 | 显示全部楼层
既然使用串口发送的AT指令,可以考虑把这个任务拆成2个部分,串口底层的收发任务只处理数据的收发,它为上层的应用提供数据接口,而通信的协议在上层的任务中解析。
尽量把每个任务都做成差分型或者递推型的程序段,我也不知道叫啥名字好,大概就是这个意思吧。然后让他们周期性的执行。
用定时器中断切出时间片给各个任务用,每当某任务等待的时间到期了,就在定时器中断里面给他发信号量或者标志位。
你这个sim卡的任务状态机的各个状态分配好自己的私用的时间片数目,执行一次sim卡任务就把当前状态对应的计数器加1,超过时间片数目后就跳转到次态。
大概就是这么设计吧,你可以自己修正完善。


其实还是加个rtos比较方便
回复

使用道具 举报

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
 楼主| 发表于 2016-6-25 14:27:59 | 显示全部楼层
xianshasaman 发表于 2016-6-24 21:29
既然使用串口发送的AT指令,可以考虑把这个任务拆成2个部分,串口底层的收发任务只处理数据的收发,它为上 ...

非常感谢您的回复,这么说我的思路大体上还是没问题的,这种精细的划分各个任务时间片也是没法避免的了?看来不用os来实现多任务非阻塞还是很困难的。

信号量这些我还是知道的,但是您所指的所谓的差分型或者递推型程序段大概指的是什么呢?

我本人接触过一点rtos,一直对rtos没什么好感,感觉要占用大量的ram,而且还有大量的上下文切换,市面上的rtos为了适用多种平台,功能比较复杂。所以还是考虑用状态机来写一个适用于自己的框架,或者以后有机会自己实现一个简单的协作式内核。
半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
回复

使用道具 举报

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
 楼主| 发表于 2016-6-25 18:30:18 | 显示全部楼层
本帖最后由 东北小辉辉 于 2016-6-25 18:36 编辑
xianshasaman 发表于 2016-6-24 21:29
既然使用串口发送的AT指令,可以考虑把这个任务拆成2个部分,串口底层的收发任务只处理数据的收发,它为上 ...

想了一下 大概理解您说的递推型程序段了 应该就是我之前说的 把一个长任务分割成N个小任务 然后顺序执行 一旦遇到需要延时的地方就切换到其他任务上去 至于任务间的通讯可以使用信号量 消息队列等方式
半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165453
金钱
165453
注册时间
2010-12-1
在线时间
2114 小时
发表于 2016-7-2 23:36:43 | 显示全部楼层
帮顶
回复

使用道具 举报

7

主题

54

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1026
金钱
1026
注册时间
2015-12-8
在线时间
447 小时
发表于 2017-7-28 22:26:28 | 显示全部楼层
学习了,看看啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-19 14:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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