0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PIL硬件支持包开发指南

MATLAB 来源:MATLAB 2023-02-28 09:21 次阅读

PIL 基本介绍

在航空和汽车等安全攸关的行业,如果采用基于模型的设计方法论(MBD),需要额外引入背靠背测试的概念,具体来说,使用模型开发的过程中,背靠背测试包含 SIL(Software-in-the-Loop)和 PIL(Processor-in-the-Loop)两种。其中 PIL 测试是验证模型和目标码(Object code,即编译链接之后的产物)等效性的有效手段,也是诸如 DO178C,ISO26262 等功能安全标准推荐的一种测试方法。

为了更好的理解本文,首先来看看什么是硬件支持包(注:PIL 功能通常是一个完整硬件支持包的其中一个功能),在 MBD 语境下,一个相对完整的硬件支持包通常包含以下组件:

Toolchain - 实现将 Simulink 模型或 M 代码一键自动化编译、链接和下载的核心手段

Device Driver - MCU/MPU/FPGA 等的外设或者片外设备,比如 ADC,PWM,GPIO,SCI 等

Code Replacement Library(CRL) - 将生成的标准代码替换成厂商的高效库函数/汇编

Processsor-In-the-Loop(PIL) - 将算法模型生成可执行文件后(如.out)放到目标硬件上执行并和主机上的仿真结果进行对比的一种等效性测试手段

External Mode - 将(算法)模型生成可执行文件后独立运行在目标硬件上并和原模型保持连接,此时原模型可理解为一种上位机“界面”,上位机模型和下位机目标码可以联动。

注:MathWorks 官方推出的硬件支持包通常是兼顾芯片级和板级,以芯片级为主,板级主要是支持一些官方或热门的开发板。

硬件支持包的开发要求开发人员具备相应的知识和技能,以下是最基本的要求:

嵌入式软硬件知识,通常包括使用 MCU/MPU/FPGA,调试工具和常用设备等技能

嵌入式软件知识,通常包括熟悉嵌入式操作系统编程,常用 IDE 的使用,通信协议,手写 makefile 等能力

Embedded Coder 定制化知识和代码生成的深刻理解

MATLAB 面向对象编程的知识

常见通信协议知识,包括 SCI,TCP/IP,CAN

只有在具备以上能力的前提下才能较好的开发出硬件支持包。另外,MathWorks 官方以及三方芯片厂商也会提供一些热门芯片的现成的硬件支持包,在确定开发之前,应该进行相关调研,如果市面上已经存在相应的支持包,建议直接使用现成的。比如 NXP 针对其各系列芯片就提供了对应的硬件支持包供客户选择。

本文将聚焦硬件支持包中 PIL 功能的开发,介绍如何开发自己的 PIL 支持包。

PIL 基本原理

a75b1ebe-b2c4-11ed-bfe3-dac502259ad0.png    

首先介绍下 PIL 的基本概念,如图所示,PIL 测试供包含两次仿真,分别是:

1)将软件的Simulink模型首先在Simulink环境中运行一次,在给定激励下会产生一些输出,记录下来;

2)接着将软件的 Simulink 模型生成代码并编译链接成可执行目标码,下载至下位机板子上运行,在相同的激励下软件在板子上运行也会产生一些输出,也记录下来。

3)最后将两次输出的结果进行等效性比对。

目前这些基本操作在 MathWorks 提供的工具链中都是傻瓜式操作,大家可自行查阅文档学习,本文不做赘述。

a83eb6ce-b2c4-11ed-bfe3-dac502259ad0.png

如图所示,一个完整的 PIL 仿真过程由以下各阶段组成:

选择三种 PIL 仿真方式中的一种启动 PIL 仿真,至于哪三种方式可参考文档

验证上位机下位机连接配置

模型生成核心代码

实例化 PIL API 组件(即 PIL Framework,就是几个 PIL 专用的 MATLAB 类文件)

继续生成额外的 PIL 需要用到的辅助代码,配合模型生成的核心代码组成一个包含上位机下位机通信和控制的完整应用代码

基于注册好的 ToolchainInfo 对象中的编译信息,调用三方交叉编译器将完整的应用代码生成可执行的目标文件。同时调用上位机的 C/C++ 编译器 (MinGW 或 Visual Studio) 把 PIL Framework 中涉及的 C/C++ 代码编译成 C Mex S Function(可简单理解成加壳的 dll 或 so 文件),这些代码主要是上位机端的 C/C++ 通讯源码。

上位机 Simulink 模型下发指令启动下位机运行目标代码

Simulink Engine 通过 C Mex S Function 和下位机进行数据交互

上位机 Simulink 模型下发指令终止下位机目标代码的运行

Simulink 模型停止 PIL 仿真

PIL 开发方法论

第一步

软硬件开发环境

开发的第一步是搭建软硬件开发环境,具体来说:

●硬件环境:开发板,调试器,外围电路,通讯接口

●软件环境:IDE,MATLAB 等,特别注意 IDE 一定要支持命令行调用,这是自动化的前提,有些 IDE 的非商业版本只允许界面操作,这个是做不了支持包的!

资料收集:各种可能涉及的参考资料,比如芯片的数据表,开发板的原理图,IDE 的使用手册等等

●通讯:PIL 会涉及上位机和下位机通信,所以通讯协议和通讯的硬件部分必须匹配,比如我们希望所开发的支持包支持上位机下位机通过 CAN 进行程序的烧写和数据交互,那么要求板子上的硬件必须支持 CAN 通讯,并且上位机一般要通过 USB-CAN 卡与下位机相连,如下图所示。理论上,任何通讯协议都可以,MathWorks 内置有部分现成的上位机通讯协议,包括串口和 TCP/IP,下位机部分仍然需要自己编写。其他协议如 CAN 则需要自己编写上位机和下位机通讯驱动。

a88f2a46-b2c4-11ed-bfe3-dac502259ad0.png

一个良好的软硬件开发环境可以通过写个 makefile 来点灯的例子进行验证。一旦完成点灯,意味着我们已经具备的基本的软硬件开发环境。

第二步

Toolchain 的开发和 Hardware Board 注册

从上文知道 PIL 仿真过程需要一键编译链接和下载目标码,这个动作是由 Toolchain 来实现的,因此开发 PIL 的第一步是开发 Toolchain。

这里先解释下 Toolchain 在本文的含义,我们知道嵌入式开发自动化脚本通常就是 makefile,而 Toolchain 大家可以认为就是 MATLAB 版本的 makefile,是用 M 语言按照一定的要求和格式进行编写,其中需要写明汇编器、编译器、链接器、下载器、格式转换器等工具的命令行调用方法,编译成目标码所需要使用的各种依赖库等。这样可以将其自动嵌入到代码生成的流程中去,实现所谓的“一键编译下载”。

为了更好的讲解后续内容,建议大家先跳到 第5步 - 细节学习,安装 C2000 的官方支持包,这是一个非常好的学习对象。这里就以 C2000 支持包为例讲解下 Toolchain 开发的要点。

C2000 支持包的安装目录(位置参考第 5 步中的截图)找到 tiCCS.m 文件,大家可以直接使用这个文件作为自己 Toolchain 开发的模板,这个文件中最核心的部分包括:

●coder.make.ToolchainInfo:定义 ToolchainInfo 对象,下图是该对象的透视图,可以说开发 Toolchain,本质就是操作这个 ToolchainInfo 对象

a8c2aba0-b2c4-11ed-bfe3-dac502259ad0.png

●使用上述对象的 getBuildTool 方法注册各类工具,比如 Assembler,Compiler,Linker,Archiver

●使用上述对象的 getPrebuildTool/getPostbuildTool 方法注册各类代码生成前后处理工具,比如编译后自动下载等

●使用上述对象的 getBuildConfiguration 方法提供不同等级的 Build Configuration,比如保留调试能力的编译配置,高度优化的编译配置等,它们的本质区别就是编译器优化等级不同

一旦完成上述内容的开发,下一步就是注册该文件,这里我们以 TI TMS320 C6678 DSP 的 Toolchain 开发为例介绍:

●TI_TMS320C6678_toolchain.m – 所开发的toolchain 的 M 代码

●sl_customization.m – 用来注册硬件板子和 Toolchain 对象,这样用户可以在 Hardware Implementation 和 Code Generation 下面看到板子和 Toolchain 可供选择。

function sl_customization(cm)
 cm.registerTargetInfo(@loc_createDevice);
end


function thisDev = loc_createDevice
 thisDev(1) = RTW.HWDeviceRegistry;
 thisDev(1).Vendor = 'Texas Instruments';
 thisDev(1).Type = 'TMS320C6678';
 thisDev(1).Alias = {};
 thisDev(1).Platform = {'Prod', 'Target'};
 thisDev(1).setWordSizes([8 16 32 32 32 32 64 32]);
 thisDev(1).LargestAtomicInteger = 'Long';
 thisDev(1).LargestAtomicFloat = 'Double';
 thisDev(1).Endianess = 'Little'; 
 thisDev(1).IntDivRoundTo = 'Zero';
 thisDev(1).ShiftRightIntArith = true; 
end

●refreshTITMS320C6678Toolchain.m – 注册 Toolchain的 脚本,包括调用 TI_TMS320C6678_toolchain.m 并将其保存成 TI_TMS320C6678_toolchain.mat 格式,进一步调用 RTW.TargetRegistry.getInstance('reset') 注册 Toolchain。

function refreshTITMS320C6678Toolchain
  %Make sure we are in the right directory
  currentDir = pwd;
  toolchainPath = getpref(' MyToolchainName', 'TOOLCHAINPATH');
  cd(toolchainPath);
  
  % Create a new configuration
  gtc= MyToolchainName_toolchain;
  tc=gtc(1); 
  save([toolchainPath ' TI_TMS320C6678_toolchain.mat'], 'tc');
  
  % Refresh customisations defined by rtwTargetInfo.m
  RTW.TargetRegistry.getInstance('reset');
  
  % Return to directory
  cd(currentDir)
end

一旦注册完成后我们就可以在模型参数配置界面上找到这个 Toolchain 作为代码生成的选项,其中:

Hardware Implementation->Hardware board 中可选择刚刚注册的板子:

a960c330-b2c4-11ed-bfe3-dac502259ad0.png

Code Generation中可选择刚刚注册的板子:

a9d7e398-b2c4-11ed-bfe3-dac502259ad0.png

最后构建一个极简的模型来验证该Toolchain能够完成模型的一键编译下载。

第三步

PIL 工具链的组成

aa207766-b2c4-11ed-bfe3-dac502259ad0.png

接着就是 PIL 最核心的开发部分,图中红色部分就是我们需要开发的内容,其中 PIL API Components 即 MathWorks 官方提供的一套标准的 PIL 开发框架,包括:上位机和下位机端各自的通讯协议,Build Process 和 Launcher等,该框架的核心就是名为 Connectivity Configuration 的几个类文件组成,以下为开发要点:

●开发 PIL Target 核心功能类(即 Connectivity Configuration 类的编写)

●桌面端和 IDE 中分别调通上位机和下位机的通讯功能,移植到核心功能类中

●下位机 Timer 配置并注册核心功能类中,主要服服务于后续下位机上任务运行时间的统计和分析

这里对上述要点进一步展开介绍下,还是以 TI TMS320 C6678 DSP 的支持包开发为例,下图是一个典型的 PIL Target 目录,这里便于我们进行讲解:

aafcad08-b2c4-11ed-bfe3-dac502259ad0.png

1)开发上位机和下位机通讯协议

比如截图中是使用串口协议,并把上位机的串口协议和下位机的串口协议代码分别放到 host_dll 和 target_src 中。如果是其他通讯协议,则把相应的协议代码分门别类放好即可。通讯协议代码需要按照一定的格式使用 rtiostream 函数进行封装。

关于 rtiostream 函数的使用请查阅文档示例或者 C2000 支持包安装目录中的代码。另外,对于串口和 TCP/IP,MATLAB 官方提供了现成的上位机协议 dll 供使用,具体位置请查阅帮助文档。

2)开发 PIL Target 核心功能类

其中 +tic6678codetargetpil 中存放了 PIL 的核心功能类,这些类文件都是通用的,大家可以直接使用官方 C2000 支持包安装目录中的 pil 代码作为模板进行微调基本就能满足要求。各个类的使用细节请直接参考文档。

ab1b5654-b2c4-11ed-bfe3-dac502259ad0.png

3)注册硬件定时器 Timer

Timer 的注册有两种方式:1)crtool;2)Timer 类。C2000 支持包使用的是 crtool 方式,在文档中搜索:Specify Hardware Timer 关键字即可找到操作指南,这种方式略微复杂些。当然也可以使用类的方式进行 Timer 注册,以下为前述 C6678 示例中 Timer 的注册方式:

classdef Timer < rtw.connectivity.Timer
% TIMER Get timing information for C6678 application 


%   Copyright 2022 The MathWorks, Inc.


    methods


        function this = Timer(varargin)
            
            this.setTimerDataType('uint32'); % i.e. unsigned long


            % Look for an input providing ticks per second
            if (nargin > 0)
        ticksPerSecond = varargin{1};
      else
        ticksPerSecond = round(1.0e9/6);
      end
      this.setTicksPerSecond(ticksPerSecond);


      % The timer counts upwards
      this.setCountDirection('up');


      % Extract path information from MATLAB Preferences
      timerSrcFolder = fullfile(fileparts(mfilename('fullpath')),'..','rtiostream','rtiostreamserial','target_src');
      
      % Configure source files required to access the timer
      timerHeaderFile = fullfile(timerSrcFolder, 'ProfilerTimer.h');
      
      timerSourceFile = fullfile(timerSrcFolder, 'ProfilerTimer.c');
      
      this.setSourceFile(timerSourceFile);
      this.setHeaderFile(timerHeaderFile);


      % Configure the expression used to read the timer
      readTimerExpression = 'profileTimerRead()';
      this.setReadTimerExpression(readTimerExpression);
    end 
  end
end

4)注册整个 PIL 硬件支持包

function rtwTargetInfo(tr)
%RTWTARGETINFO Target info callback,register individual targets with Coder Target


% Copyright 2022 The MathWorks, Inc.


tr.registerTargetInfo(@loc_createToolchain);
tr.registerTargetInfo(@loc_createConfig);
codertarget.TargetRegistry.addToTargetRegistry(@loc_registerThisTarget);
codertarget.TargetBoardRegistry.addToTargetBoardRegistry(@loc_registerBoardsForThisTarget);
end


% -------------------------------------------------------------------------
% Create ToolchainInfoRegistry entries for TI TMS320C6678
function config = loc_createToolchain
config = coder.make.ToolchainInfoRegistry; % initialize


% Append to last in the toolchain registry base
config(end).Name   = 'TI TMS320C6678 Toolchain v1.0 | gmake (win64)';


toolchainPath = mfilename('fullpath');
[toolchainDir, ~] = fileparts(toolchainPath);


config(end).FileName = fullfile(toolchainDir,'toolchain','TI_TMS320C6678_toolchain_win64.mat'); %MODIFY


%List the platform or platforms supported by the custom toolchain
%'*' means it supports any hardware device.
config(end).TargetHWDeviceType  = {'*'};


%config(end).Platform        = {computer('arch')};
config(end).Platform = {'win64'};
end


function ret = loc_registerThisTarget()
ret.Name = 'TI TMS320C6678';
[targetFilePath, ~, ~] = fileparts(mfilename('fullpath'));
ret.TargetFolder = targetFilePath;
end




% -------------------------------------------------------------------------
function boardInfo = loc_registerBoardsForThisTarget()
target = 'TI TMS320C6678';
[targetFolder, ~, ~] = fileparts(mfilename('fullpath'));
boardFolder = codertarget.target.getTargetHardwareRegistryFolder(targetFolder); % Point to folder registry/targethardware
boardInfo  = codertarget.target.getTargetHardwareInfo(targetFolder, boardFolder, target);
end




% -------------------------------------------------------------------------
% Specify settings for valid PIL configuration
function config = loc_createConfig


% Create object for serial connectivity configuration
config(1) = rtw.connectivity.ConfigRegistry;
% Assign connectivity configuration name
config(1).ConfigName = 'TMS320C6678 PIL Serial';
% Associate the connectivity configuration with the connectivity
% API implementation
config(1).ConfigClass = 'tic6678codetargetpil.SerialConnectivityConfig';
% match TI C6678 toolchains
config(1).Toolchain = {'TI TMS320C6678 Toolchain v1.0 | gmake (win64)'};
% Match only ert.tlc
config(1).SystemTargetFile = {'ert.tlc'};


% Through the HardwareBoard and TargetHWDeviceType properties,
% define compatible code for the target connectivity configuration
% match only TI C6678
config(1).HardwareBoard = {};
config(1).TargetHWDeviceType = {'Texas Instruments->TMS320C6678'};
end

第四步

PIL 支持包的测试

可以自行构建一个简单的模型,使用 SIL/PIL Manager 进行测试,具体的操作技巧请查阅文档,这里不做赘述。

ab508f18-b2c4-11ed-bfe3-dac502259ad0.png

第五步

细节学习

限于篇幅和嵌入式本身的复杂性,本文无法面面俱到,最好的学习资料就是仔细研究一些现成的硬件支持包,比如 MathWorks 官方提供的 C2000 硬件支持包:

大家安装完成后,结合本文,仔细翻阅支持包安装目录,基本就能把各种细节摸清楚。帮助文档中也有 PIL 的示例和资料,相对来说篇幅较多也比较零散,需要耐心阅读。R2019a 引入了 target Package,即一组高度抽象的 API 来便利化硬件支持包的开发,由于其高度抽象性,建议仍然使用本文描述的方法进行 PIL 支持包开发,这样调试起来会方便很多。

abaaa43a-b2c4-11ed-bfe3-dac502259ad0.png

说的再多,都不如找一块板子实际开发一遍,祝大家都能掌握PIL开发的方法论,在项目中引入PIL测试环节,以期提高产品质量,减少后期枯燥地调试工作。






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1603

    文章

    21326

    浏览量

    593242
  • GPIO
    +关注

    关注

    16

    文章

    1135

    浏览量

    50580
  • MBD
    MBD
    +关注

    关注

    0

    文章

    22

    浏览量

    8818
  • PIL
    PIL
    +关注

    关注

    0

    文章

    18

    浏览量

    8507
  • SIL
    SIL
    +关注

    关注

    0

    文章

    9

    浏览量

    2468

原文标题:PIL (Process-in-the-Loop) 硬件支持包开发指南

文章出处:【微信号:MATLAB,微信公众号:MATLAB】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Openwrt开发指南 第24章 配置开发支持U盘

    Openwrt开发指南 第24章 配置开发支持U盘
    的头像 发表于 07-13 08:55 1379次阅读
    Openwrt<b class='flag-5'>开发指南</b> 第24章 配置<b class='flag-5'>开发</b>板<b class='flag-5'>支持</b>U盘

    Atlas 200 AI加速模块硬件开发指南.pdf

    Atlas 200 AI加速模块硬件开发指南.pdf
    发表于 12-22 16:18 25次下载

    AN2586_STM32F10xxx硬件开发指南

    AN2586_STM32F10xxx硬件开发指南
    发表于 11-21 08:11 3次下载
    AN2586_STM32F10xxx<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    AN057 GD32F3x0系列硬件开发指南

    AN057 GD32F3x0系列硬件开发指南
    发表于 02-23 19:00 1次下载
    AN057 GD32F3x0系列<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    AN056 GD32F4xx系列硬件开发指南

    AN056 GD32F4xx系列硬件开发指南
    发表于 02-23 19:01 1次下载
    AN056 GD32F4xx系列<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    GD32W51x硬件开发指南

    GD32W51x硬件开发指南
    发表于 03-01 18:43 1次下载
    GD32W51x<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    AN078 GD32E50x系列硬件开发指南

    AN078 GD32E50x系列硬件开发指南
    发表于 03-01 18:47 0次下载
    AN078 GD32E50x系列<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    AN076 GD32F10x系列硬件开发指南

    AN076 GD32F10x系列硬件开发指南
    发表于 03-01 18:53 1次下载
    AN076 GD32F10x系列<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    AN074 GD32E23x系列硬件开发指南

    AN074 GD32E23x系列硬件开发指南
    发表于 03-01 18:57 1次下载
    AN074 GD32E23x系列<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    AN069 GD32L233系列硬件开发指南

    AN069 GD32L233系列硬件开发指南
    发表于 03-01 19:01 2次下载
    AN069 GD32L233系列<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>

    兆易创新AN056 GD32F4xx系列硬件开发指南

    兆易创新AN056GD32F4xx系列硬件开发指南AN056GD32F4xx系列硬件开发指南
    发表于 10-19 17:26 2次下载

    兆易创新AN057 GD32F3x0系列硬件开发指南

    兆易创新AN057GD32F3x0系列硬件开发指南AN057GD32F3x0系列硬件开发指南
    发表于 10-19 17:26 0次下载

    兆易创新AN069 GD32L233系列硬件开发指南

    兆易创新AN069GD32L233系列硬件开发指南AN069GD32L233系列硬件开发指南
    发表于 10-19 17:26 1次下载

    兆易创新GD32W51x硬件开发指南

    兆易创新GD32W51x硬件开发指南GD32W51x硬件开发指南
    发表于 10-19 17:26 0次下载

    GD32L233硬件开发指南

    电子发烧友网站提供《GD32L233硬件开发指南.pdf》资料免费下载
    发表于 01-05 10:26 2次下载
    GD32L233<b class='flag-5'>硬件</b><b class='flag-5'>开发指南</b>