为了方便大家阅读,从这章开始在章节名中添加该章节要讲的主要的东西。
本章给大家讲一个最简单的Simulink模型:
在处理应用逻辑时常常会判断车速信号来得到车是否静止,如果车已经跑起来了,很多功能都会被禁用,比如诊断,开关门等。

以上模型就是一个最简单的车速判断逻辑,int16型数据VehicleSpeed(单位km/h)先得到其绝对值然后再和Constant数3做比较,如果绝对车速大于等于3km/h那么车是Driving状态。如果小于3km/h那么车即可认定为静止状态。
我们来生成以下代码,看看代码是怎么样的:
点击APP下的Embedded Coder,

点击Quick Start,

点击next,

这里可以选择整个Model或者选择Model下的某一个子系统,这里直接选择整个Model,点击next,

当前只是看下基本代码,直接选择C Code 和 单Instance(Instance及autosar相关的选项都是AUTOSAR下相关的属性及配置,后续会有基于AUTOSAR下模型开发的文章)。点击next,

点击next,

这里选择一些基本类型的内存长度,直接选择默认的,点击next,

这里是选择执行最快或者RAM最少,为了让逻辑看起来更明了,选择执行最快,点击next,

直接点击next,

点击finish,
回到Simulink,

点击build,
代码就生成了,

生成了上图的四个.c,.h文件
进入Demo.h
typedef struct {int16_T VehicleSpeed; /* '<Root>/VehicleSpeed' */
} ExtU;/* External outputs (root outports fed by signals with default storage) */
typedef struct {boolean_T VehicleIsDriving; /* '<Root>/VehicleIsDriving' */
} ExtY;/* External inputs (root inport signals with default storage) */
extern ExtU rtU;/* External outputs (root outports fed by signals with default storage) */
extern ExtY rtY;/* Model entry point functions */
extern void Demo_initialize(void);
extern void Demo_step(void);
可以看到,Embedded Coder将模型的输入做了一个结构体,对输出也做了一个结构体,这样出来的代码结构比较清晰,在代码debug的过程中会很方便地跟踪这些变量。同时生成了Demo_initialize(void)和Demo_step(void)两个函数,这两个函数在嵌入式RTOS系统用中是很重要的函数,每个SWC(Software component)都必须有这两个函数,Demo_initialize(void)一般用在系统startup时,Demo_step(void)会被assign到一个固定的task中周期执行。
再看下Demo.c
#include "Demo.h"/* External inputs (root inport signals with default storage) */
ExtU rtU;/* External outputs (root outports fed by signals with default storage) */
ExtY rtY;/* Model step function */
void Demo_step(void)
{int16_T tmp;/* Abs: '<Root>/Abs' incorporates:* Inport: '<Root>/VehicleSpeed'*/if (rtU.VehicleSpeed < 0) {tmp = (int16_T)-rtU.VehicleSpeed;} else {tmp = rtU.VehicleSpeed;}/* End of Abs: '<Root>/Abs' *//* Outport: '<Root>/VehicleIsDriving' incorporates:* RelationalOperator: '<Root>/Relational Operator'*/rtY.VehicleIsDriving = (tmp >= 3);
}/* Model initialize function */
void Demo_initialize(void)
{/* (no initialization code required) */
}
代码中可以清楚地看出,其先用了一个temp得到VehicleSpeed的绝对值,然后在和3做比较并输出给VehicleIsDriving
打开rtwtype.h
/*=======================================================================** Fixed width word size data types: ** int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers ** uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers **=======================================================================*/
typedef signed char int8_T;
typedef unsigned char uint8_T;
typedef short int16_T;
typedef unsigned short uint16_T;
typedef int int32_T;
typedef unsigned int uint32_T;
typedef long long int64_T;
typedef unsigned long long uint64_T;/*===========================================================================** Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, ** ulong_T, ulonglong_T. **===========================================================================*/
typedef unsigned char boolean_T;
typedef int int_T;
typedef unsigned int uint_T;
typedef unsigned long ulong_T;
typedef unsigned long long ulonglong_T;
typedef char char_T;
typedef unsigned char uchar_T;
typedef char_T byte_T;
rtwtype.h是simulink的Realtime Workshop的type定义,提供给各个SWC.h做基本类型引用。在嵌入式系统中,每个SWC在代码生成是都会生成一个rtwtype.h,最终只包含一个大家通用就行了。
最后ert_main.c(Embedded realtime target)没什么用,其只为生成一个示例去调用Demo_initialize(void)和Demostep(void)两个函数,在实际的实时嵌入式系统中,我们会将swc.c, swc.h加入工程中,用系统中提供的task_init(), task_xxms()来调用这两个函数。当然大家也可以将ert_mian.c及swc.c swc.h rtwtype.h加入visual studio工程中进行验证(不过用处不是很大,仅限学习使用)。
以上便是simulink基本模块的搭建以及Embedded coder的基本使用相关的内容,需要提的是不同的simulink版本在simulink的搭建方面是一样的,但是其Embedded coder变化较大,本文在是基于R2020a版本的Embedded coder讲解的,大家在生成代码过程中有什么问题可以自行百度。