![ba97f668d62252d9a628e7214cd0432d.png](https://i-blog.csdnimg.cn/blog_migrate/a32f4f3da1f6be85f4d8acaa7832aae3.jpeg)
![1bac137740d9a89d1cee92f5f642b14d.png](https://i-blog.csdnimg.cn/blog_migrate/6600bc389792f31cc9b8cfecdc8dffe5.png)
上次我们写了一个可以自动化配置模型选项的Block,双击它即可完成模型的配置,即配置了模型的基本信息,也配置了系统tlc、makefile模板、代码模板等和代码生成关系紧密的几个文件。
这次我们关注的是mytarget_proc.tlc这两个文件,它对应的是ERTCustomFileTemplate这个选项,可以用它来生成自定义的main函数,真正和我们的硬件发生联系。
翻箱倒柜从灰尘堆里把STM32开发板找出来,硬件我们就用他了,编译器用Keil,大家如果使用不同硬件和编译器也无所谓,根据自己的情况进行调整。
因为使用STM32我对mytarget_configuration函数进行了修改如下:
set_param(cs,'ProdHWDeviceType','ARM7');
改成
set_param(cs,'ProdHWDeviceType','ARM Cortex');
之前有讲过,在toolbox的根目录下,有一个src文件,用来放支撑模型运行的源代码。
mytargetroot/src
这个目录放喜闻乐见的C源码,例如启动、定时等运行框架代码,也包含硬件驱动的接口。
我准备的文件如下,熟悉STM32的朋友应该会看着比较眼熟,同时也会发现里面没有main.c。main.c我们会在代码生成的阶段把它生成出来,在开发阶段需要做的是编写一个生成的模板,这个生成的模板就是mytarget_proc.tlc。
![c2d8a0c6b9cd53c3e01818cbd93ea341.png](https://i-blog.csdnimg.cn/blog_migrate/7366c874575d75a15d8ee1d5bcc7c005.png)
mytarget_proc.tlc的内容看起来既熟悉又陌生,熟悉的是大段的C语言代码,陌生的是里面夹杂着少许TLC代码。它的主要功能是创建了一个新的源文件main.c,并通过LibGetMdlPubHdrBaseName、LibCallModelInitialize、LibCallModelStep、LibCallModelTerminate等几个TLC函数包含模型头文件,调用模型的initialize、step、terminate等函数。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
在模型生成后,mytargetroot/src目录下应当是一个完整的可编译的STM32工程,这个工程不是指Keil工程,为了实现在代码生成后的自动化编译,我们编写makefile文件,让matlab来启动编译。
MAKE = C:TDM-GCC-64binmake
KEIL_PATH = C:KeilARM
ARMCC = $(KEIL_PATH)BIN40armcc
ARMASM = $(KEIL_PATH)BIN40armasm
ARMAR = $(KEIL_PATH)BIN40armar
ARMLINK = $(KEIL_PATH)BIN40armlink
FROMELF = $(KEIL_PATH)BIN40fromelf
CFLAGS := -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork
CMACRO := -DSTM32F10X_HD -DUSE_STDPERIPH_DRIVER
ASMFLAGS := --cpu Cortex-M3 -g --apcs=interwork --pd "__MICROLIB SETA 1"
LINKFLAGS := --cpu Cortex-M3 --library_type=microlib --strict
MAP := --autoat --summary_stderr --info summarysizes --map --xref --callgraph --symbols
INFO := --info sizes --info totals --info unused --info veneers
TARGET = .Outputmytarget
OBJMAP := .Output*.map
OBJHTM := .Output*.htm
OBJAXF := .Output*.axf
SRCS = ..Usersrcmain.c
OBJS = ..Modelmain.o
..Startupstartup_stm32f10x_hd.o
..LibrariesCMSIScore_cm3.o
..LibrariesCMSISsystem_stm32f10x.o
..LibrariesCMSISstm32f10x_it.o
INC += -I$(KEIL_PATH)RV31INC
INC += -I$(KEIL_PATH)CMSISInclude
INC += -I$(KEIL_PATH)INCSTSTM32F10x
INC += -I..LibrariesCMSIS
INC += -I..LibrariesSTM32F10x_StdPeriph_Driverinc
%.o:%.c
$(ARMCC) $(CFLAGS) $(INC) $(CMACRO) $< -o $@
%.o:%.s
$(ARMASM) $(ASMFLAGS) $(INC) $< -o $@
mytarget:$(OBJS)
$(ARMLINK) $(LINKFLAGS) --libpath "$(KEIL_PATH)RV31LIB" --scatter=mytarget.sct $(MAP) $(INFO) --list $(TARGET).map $^ ..LibrariesSTM32F10xR_V3.0.lib --output=$(TARGET).axf
$(FROMELF) --bin -o $(TARGET).bin $(TARGET).axf
$(FROMELF) --i32 -o $(TARGET).hex $(TARGET).axf
del $(OBJHTM) $(OBJAXF) $(OBJS)
.PHONY : clean
clean:
del $(OBJS) *.map *.htm
回想上次的ConfigureMyTarget模块,我们并没有为它编写TLC文件,这会导致在模型代码生成过程中需要支持noninlined S-Functions,依赖non-finite numbers和floating-point numbers,从而生成例如rtGetIf.c等多个C文件,为了避免生成我们不想要的文件,给ConfigureMyTarget模块编写如下TLC。
%implements "ConfigureMyTarget" "C"
下面我们来验证一下,建立一个模型,模型名字叫demo,只是放了一个配置模型的模块。
![46c228b2277dc8209420be041c0306b8.png](https://i-blog.csdnimg.cn/blog_migrate/2a0f6f5d8c23051db38e416162e25cdd.png)
双击配置模型,然后Build,模型代码和main.c文件按照预期生成。
![0f39f6423f175d7feaf6a5ab31e3e906.png](https://i-blog.csdnimg.cn/blog_migrate/e4fea89192d386c9b5a10eb9a65c3b56.jpeg)
ok,这次就到这里,下次我们来看如何自动化的编译生成的文件。
![76676c3366ec795c8d8c6d16cb26d7cb.png](https://i-blog.csdnimg.cn/blog_migrate/60f6679da5db0620f39193abd35ecffc.jpeg)