Simulink代码生成:通过Chart模块进行多个周期调度

本文研究如何通过Chart模块进行多个周期调度。

1 问题引入

在很多以前的博客中,博主用Simulink生成的代码中,包含一个Step函数。在代码编译的过程中会把这个Step函数放入OS调度的函数中,譬如Task_5ms()函数内,这个函数就会每隔5ms被操作系统执行一次。

但是博主最近在工作中遇到一个需求是,一个Simulink模型中的不同子系统以不同的周期被调度,但是生成的代码还得是一个step函数。这就需要在模型内实现多个周期调度,研究了一下认为可以通过Chart模块发送不同的事件(Event)来完成这个任务。

2 Simulink建模

博主通过简单的Simulink建模,来记录一下这个方案的思路。

2.1 Chart模型

在模型中,Chart模块充当了一个“调度器”的角色,以不同的频率的事件调度外部的子系统。首先默认这个模型的调度事件是2.5ms。

1)新建一个Simulink模型,拖入一个Chart模块如图所示;
在这里插入图片描述
2)双击进入Chart模块,在其中建立如下图所示的State,命名为Scheduler;
在这里插入图片描述
其中,进入Scheduler时(en),会发送call_2d5ms、call_5ms、call_10ms三个事件。然后在这个状态内(du)持续发送这三个事件,但是频率不同。call_2d5ms事件是每个周期发送一次,call_5ms事件是每两个周期发送一次,call_10ms事件是每4个周期发送一次。这样,由于整个模型的调度周期是2.5ms,所以call_2d5ms事件是2.5ms触发一次,call_5ms事件是5ms触发一次,call_10ms事件是10ms触发一次。

3)在属性栏将这三个事件都设为输出事件;
在这里插入图片描述
4)退出到上一层会看到,Chart模块多出了三个端口,用Goto模块将这三个端口分别引出以备后面的Function-Cal子系统使用。
在这里插入图片描述
5)在模块的properties中取消勾选Execute (enter) Chart At Initialization这样的话,生成代码就不会初始化Chart里面的内容了;
在这里插入图片描述

2.2 触发子系统

建立三个Function-Call子系统,分别由上文的Chart模块的三个输出事件调用;
在这里插入图片描述
每个子系统都是相同的输入port,但是子系统内的Gain模块的放大系数不一样。其中2.5ms的子系统对于着2倍,5ms的子系统对于着3倍,10ms的子系统对于着4倍.这样方便观察生成的代码。

3 代码生成与分析

配置好Embedded Coder后,Ctrl + B生成代码,观察Step函数内容;
在这里插入图片描述
函数一开始会使用i1,i2,i3三个全局变量作为计数器,每次调度step函数时,如果小于1,2或4就会自加1。
在这里插入图片描述
后面的代码中,如果i1,i2,i3分别等于1,2或4的时候,就会执行对于子系统里面的内容。这就意味着模型中的Function1每一次step函数执行一次,Function2每两次step函数执行一次,Function3每四次step函数执行一次。只要把step函数放进2.5ms中周期调度,这三个子系统就会以2.5ms,5ms,10ms来执行,也就完成了博主一开始提出的问题。

4 总结

本文研究通过Chart模块在一个模型中进行多个周期调度的办法,适用的场景比较特殊,但是可以很方便地解决这类问题。

>>返回个人博客总目录

  • 18
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值