本文主要是介绍便携式航电实时系统测试平台实时脚本介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
实时脚本在ETest中作为下位机脚本,运行在VXWorks环境下。
实时脚本为C++脚本,符合C++ 17规范。
同时,实时脚本还带有ETest提供的扩展API,提供了一系列服务和支持。本章主要介绍这些扩展API。
本节介绍对ETest下位机接口设备硬件进行操作,完成通信的接口API。
所有接口类均在命名空间 Kiyun::LowerComputer::Rasl::Device
中。
所有接口都采用设备与通道两层结构,通道统一命名为 Channel_T
,作为设备的内嵌类。如串行通信口,类名为 Com_T
,其通道为 Com_T::Channel_T
。
每个接口的方法主要有两组,分别是 read/write
和 intRead/asyncWrite
。其中前一组是阻塞式读/写,后一组是异步(非阻塞式)读/写。其中,异步读/写均为立即返回,不等待读写操作完成;读/写完成后调用回调函数。注意有的设备没有异步读/写API。
在正常使用中,接口对象由 ETest 根据测试连接图自动构造,并以图中的通道名为对象名,可在代码中直接使用。
使用模数转换通道主要用到的类型是Ad_T
类型。本节对模数转换通道进行介绍。
本节所描述的类型所在命名空间均为:Kiyun::LowerComputer::Rasl::Device
。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,模数转换操作主要由Ad_T::Channel_T
类型完成。
在使用ETest进行仿真模型设计和设备规划过程中,可以建立模数转换通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建Ad_T::Channel_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的采集操作。
如,在以下范例中,对象f_ad
即为Ad_T::Channel_T
类型的对象,可以用来完成模拟量采集功能。
单次采集:
//判断通道初始化是否成功,初始失败退出 |
单次采集多个点:
//判断通道初始化是否成功 |
连续采集:
if (!f_ad.isValid()) { |
-
-
-
- Ad_T类
-
-
本类型是模数转换操作类型。它包含了IntReader_T
类型和Channel_T
类。
IntReader_T
类型
在进行中断读取的时候,需要用到一个函数类型作为参数,当读取操作完成的时候,本函数会被调用。
类型定义为:
typedef std::function<bool(float*,size_t,Error_T)> IntReader_T; |
-
-
-
- Ad_T::Channel_T类
-
-
本类型的对象是进行AD采集的主体。具有以下方法:
isValid
方法
函数原型:bool isValid() const
path
方法
返回通道的标识,可用于在数据上传时构造上传通道。
函数原型:Path_T path() const
read
方法一
函数原型:float read()
read
方法二
函数原型:BOOL read(float* buf, size_t size)
参数:buf
:存放采集到数据的地址;size
:buf
的长度(采集点数)
intRead
方法
进行通道注册连续采集。连续采集工作与单次采集工作不能同时进行。
函数原型:void intRead(const IntRead_T& hdl)
参数:hdl
:回调函数,函数返回值表示“是否继续接收”,true
继续,false
停止;
isRuning
方法
判断是否存在连续采集任务。
函数原型:BOOL isRuning()
返回值:TRUE
:存在连续采集任务,FALSE
:不存在连续采集任务
start
方法
函数原型:BOOL start()
返回值:TRUE
:成功打开或者已经存在任务,FALSE
:打开失败
stop
方法
停止连续采集任务。
函数原型:BOOL stop()
返回值:TRUE
:成功关闭或者不存在连续采集任务,FALSE
:关闭失败
reset
方法
重置连续采集通道
函数原型:BOOL reset ()
返回值:TRUE
:成功清除已注册的连续采集通道,FALSE
:重置失败(采集任务正在进行)
使用数模转换通道主要用到的类型是Da_T
类型。本节对数模转换通道进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,数模转换操作主要由Da_T::Channel_T
类型完成。
在使用ETest进行仿真模型设计和设备规划过程中,可以建立数模转换通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建Da_T::Channel_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的采集操作。
如,在以下范例中,对象da
即为Da_T::Channel_T
类型的对象,可以用来完成模拟量转换输出功能。
int kiyunMain() { if(!da.isValid()) { } da.write(5.0); Timer_T::delay(5);// Da 保持输出5s da.stop();// 禁止输出(Da退出会自动调用) return 0; } |
-
-
-
Da_T::Channel_T
类
-
-
本类型所在命名空间为:Kiyun::LowerComputer::Rasl::Device
,是进行DA转换的主体。具有以下方法:
isValid
方法
函数原型:bool isValid() const
path
方法
返回通道的标识,可用于在数据上传时构造上传通道。
函数原型:Path_T path() const
write
方法
函数原型:void write(float value)
注:Da32(AECDA-CPCI-32)写操作需要延迟 25ms,Da8(AECDA-CPCI-8-S2)输出间隔应至少1us
start
方法
(
write
方法会自动调用start
方法开始输出)。
函数原型:void start()
stop
方法
函数原型:void stop()
使用串口总线主要用到的类型是COM_T
类型。本节对串口总线操作进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,串口总线操作主要由Com_T::Channel_T
类型完成。
在使用Etest进行仿真模型设计和设备规划过程中,可以建立串口总线通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建Com_T::Channel_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的采集操作。
对象com0
和
com1
即为Com_T::Channel_T
类型的对象,可以用来完成串口总线功能。
示例代码如下:
/** 系统固定头文件 */ |
-
-
-
Com::Channel_T
类
-
-
本类型所在命名空间为:Kiyun::LowerComputer::Rasl::Device
,是进行串口总线操作的主体。具有以下类型和方法:
isValid
方法
函数原型:bool isValid() const
path
方法
函数原型:Path_T path() const
WriteHandler_T
类型
typedef std::function<void(size_t, Error_T)> WriteHandler_T;
asyncWrite
方法
函数原型:void asyncWrite(const char* buf, size_t size, WriteHandler_T whenDone)
参数:buf
:输出数据的首地址;size
:数据长度;whenDone
:回调函数。
IntRead_T
类型
typedef std::function<bool(char*, size_t, Error_T)> IntReader_T;
intRead
方法
函数原型:void intRead(const IntRead_T& hdl)
参数:hdl
:回调函数,函数返回值表示“是否继续接收”,true
继续,false
停止
read
方法
函数原型:Error_T read(char* buf, size_t size, Timeout_T timeout = 1_s)
参数:buf
:存放输入数据的地址;size
:读取的字节数;timeout
:超时等待时间,默认为1s
write
方法
函数原型:Error_T write(const char* buf, size_t size, Timeout_T timeout = 1_s)
参数:buf
:存放输出数据的地址;size
:输出的字节数;timeout
:超时等待时间,默认为1s
- clear方法
清除缓冲区
函数原型:void clear();
参数:无。
返回值:无。
- empty方法
判断缓冲区是否为空
函数原型:bool empty();
参数:无。
返回值:布尔型,是/否为空。
使用CAN总线主要用到的类型是Can_T
类型。本节对CAN总线操作进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,CAN总线操作主要由Can_T::Channel_T
类型完成。
在使用ETest进行仿真模型设计和设备规划过程中,可以建立CAN总线通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建Can_T::Channel_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的采集操作。
如,交联环境图按照下图配置。
对象f_can1
和f_can2
即为Can_T::Channel_T
类型的对象,可以用来完成CAN总线功能。
示例脚本如下:
/** 系统固定头文件 */ |
-
-
-
Can::Channel_T
类
-
-
本类型所在命名空间为:Kiyun::LowerComputer::Rasl::Device
,是进行CAN总线操作的主体。具有以下类型和方法:
isValid
方法
函数原型:bool isValid() const
path
方法
函数原型:Path_T path() const
asyncWrite
方法
函数原型:void asyncWrite(CanFrame_T& can, const WriteHandler_T& hdl)
intRead
方法
函数原型:void intRead(const IntRead_T& hdl)
参数:hdl
:回调函数,函数返回值表示“是否继续接收”,true
继续,false
停止。
read
方法
同步读。
函数原型:BOOL read(Can_T::CanFrame_T & frame, Timeout_T timeout = 1_s)
参数:frame
:存放输入数据的地址;timeout
:超时等待时间,默认为1s。
write
方法
同步写。
函数原型:BOOL write(const Can_T::CanFrame_T & frame,Timeout_T timeout = 1_s);
参数:frame
:存放输出数据的地址;timeout
:超时等待时间,默认为1s
使用数字量输入/输出操作主要用到的类型是Dio_T类型。本节对数字量输入/输出操作进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,数字量输入/输出操作主要由Dio_T::Channel_T
类型完成。
在使用Etest进行仿真模型设计和设备规划过程中,可以建立数字量输入/输出通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建Dio_T::Channel_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的采集操作。
如,在以下范例中,创建交联环境图如下:
对象CH_
数字输入
_1
和CH_
数字输出
_1
即为Dio::Channel_T
类型的对象,可以用来完成数字量输入/输出功能。
在设备规划中需要设置DI通道的属性“跳变检测模式”为正确的模式,才能在intRead
函数中进行跳变沿检测处理。
示例代码如下:
/** 系统固定头文件 */ |
-
-
-
Dio::Channel_T
类
-
-
该类所在的命名空间:Kiyun::LowerComputer::Rasl::Device
。具有以下方法:
isValid
方法
函数原型:bool isValid() const
path
方法
函数原型:Path_T path() const
read
方法
函数原型:BOOL read();
write
方法
函数原型:void write(BOOL status)
参数:status
:输出状态,TRUE
为高电平,FALSE
为低电平
intRead
方法
函数原型:void intRead(Channel_T::IORVectorHandler_T inputRVector)
参数:inputRVector
跳变检测回调函数,函数说明为:
Bool inputRVector
(
int id
,
int state
)
参数id
为发生跳变的通道号。
参数state
为当前通道的状态(0或者1)。
返回值表示“是否继续检测”,true
继续,false
停止。
使用UDP接口操作主要用到的类型是M1553_T
类型。本节对1553B接口操作进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,1553B接口操作主要由M1553_T
类型完成。
在使用Etest进行仿真模型设计和设备规划过程中,可以建立1553BC、1553RT、1553MT、1553BSP通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建对于
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的读/写操作。
创建仿真模型如下图所示。
- 1 1553范例仿真模型
在设备规划中,选中设备,在“属性”窗体编辑属性,建立消息列表。
- 2 1553范例设备规划
- 3 1553范例消息编辑器
编写如下实时脚本,完成消息的收发。
同步读写:
/** 系统固定头文件 */ |
异步读写
/** 系统固定头文件 */ |
-
-
-
- M1553_T类
-
-
类型所在命名空间:Kiyun::LowerComputer::Rasl::Device
。
- isValid方法
检查通道是否有效。
函数原型:bool isValid() const
参数:无
返回值:true
:对象初始化有效,fasle
:对象初始化无效
path
方法
获取通道标识。
函数原型:Path_T path() const
参数:无
返回值:通道标识符
isRunning
函数原型:BOOL isRunning ()
函数功能:BC 是否开始消息处理
参数说明:无
返回值:TRUE : BC正在运行;FALSE:BC 未运行
write
函数原型:BOOL write(uint16_t msgId = 4095, BOOL bRun = TRUE)
函数功能:BC消息运行控制函数,仅供DSP通道使用
参数说明:msgid : 消息的id号,从0开始编号,到4094结束 ,id 大于4094则表示运行所有消息
bRun:消息运行控制位:
TRUE:消息编号为msgId的消息开始执行
FALSE:消息编号为msgId的消息不再执行
返回值:TRUE:表示执行成功;FALSE :表示失败
write
函数原型:BOOL write(const uint16_t* data, size_t size)
函数功能:修改发送BC,RT 消息的数据块
参数说明:data: 数组首地址 ; size:数组大小,最多32个字,RT为循环缓冲size最大为4096
返回值:TRUE:表示执行成功;FALSE :表示失败
注:write之后需要DSP 执行此消息才能发送数据,否则只修改了发送缓冲区数据
read
函数原型:BOOL read(uint16_t* data, size_t size,size_t& res);
函数功能:BC RT MT接收到的数据
参数说明:data: 存放收到的数据字的数组首地址
size: 存放数据的数组大小
res:实际读到的数据字个数
返回值:TRUE:表示执行成功;FALSE :表示当前没有可读的数据
注:没有读到数据时,请检查DSP是否执行了此消息。
read
函数原型:std::vector<uint8_t> read()
函数功能:BC RT MT接收到的数据的字节流(字节顺序小端)
参数说明: 无
返回值: vector的size() 不为0则表示读取成功,否则读取失败
read
函数原型:BOOL read(RecvMsg_T* msg, size_t size,size_t& res)
函数功能:MT同步读,仅供MT通道使用
参数说明: msg:MT接收数据消息的缓冲区地址
size :缓冲区大小
res:实际读取到的消息个数
返回值:TRUE:读取成功;FALSE:读取失败(没有数据)
intRead
函数原型:void IntRead(const IntReader_T& hdl)
函数功能:BC RT MT中断读,通道取值范围0~1
参数说明: hdl:回调函数,函数返回值表示“是否继续接收”,true继续,false停止
返回值: 无
-
-
- ARINC429接口
-
使用ARINC429接口操作主要用到的类型是M429_T
类型。本节对ARINC429接口操作进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,ARINC429接口操作主要由M429_T
类型完成。
在使用Etest进行仿真模型设计和设备规划过程中,可以建立429S通道和429D通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建M429_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的读/写操作。
如,在以下范例中,创建仿真模型如下。
- 4 429范例仿真模型
编写实时测试用例如下所示。
1、同步读写功能
/** 系统固定头文件 */ |
- 异步读写功能
/** 系统固定头文件 */ |
-
-
-
- M429_T类
-
-
类型所在命名空间:Kiyun::LowerComputer::Rasl::Device
。
- isValid
函数原型:bool isValid() const(强烈建议使用前判断通道合法性)
函数功能:检测通道是否有效
参数说明:无
返回值:true:通道有效,fasle:通道无效
- path
函数原型:Path_T path() const
函数功能:获取通道标识
参数说明:无
返回值:通道标识符
- asyncWrite
函数原型:void asyncWrite(const uint32_t * buf, uint16_t size, WriteHandler_T whenDone)
函数功能:异步输出,通道取值范围0~7
参数说明:buf:429输出数据的首地址;size :数组的大小(最多511个);timeout:超时等待时间,默认为1s
返回值:无
- intRead
函数原型:void intRead(const IntRead_T& hdl)
函数功能:中断读,通道取值范围0~7
参数说明:hdl:回调函数,函数返回值表示“是否继续接收”,true继续,false停止
返回值:无
- read
函数原型:Error_T read (uint32_t* buf, uint16_t readSize,Timeout_T timeout = 1_s);
函数功能:同步读,通道取值范围0~7
参数说明:buf:存放429输入数据的地址; readSize :需读取的数据个数(需要buf能存放下);timeout:超时等待时间,默认为1s
返回值:错误码,0表示成功,其他则表示有出错
- write
函数原型:Error_T write(const uint32_t* buf, uint16_t size, Timeout_T timeout = 1_s);
函数功能:同步写,通道取值范围0~7
参数说明:buf:存放输出数据的首地址;size :数组的大小(最多511个);timeout:超时等待时间,默认为1s
返回值:错误码,0表示成功,其他则表示有出错
-
-
- FC接口
-
使用FC接口操作主要用到的类型是FC_T
类型。本节对FC接口操作进行介绍。
-
-
-
- 使用方法及范例
-
-
在ETest系统中,FC接口操作主要由FC_T
类型完成。
在使用Etest进行仿真模型设计和设备规划过程中,可以建立FC通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建MFC_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的读/写操作。
建立交联环境图如下:
编写实时测试用例如下所示。
/** 系统固定头文件 */ |
-
-
-
- FC_T类
-
-
类型所在命名空间:Kiyun::LowerComputer::Rasl::Device
。
- isValid
函数原型:bool isValid() const(强烈建议使用前判断通道合法性)
函数功能:检测通道是否有效
参数说明:无
返回值:true:通道有效,fasle:通道无效
- path
函数原型:Path_T path() const
函数功能:获取通道标识
参数说明:无
返回值:通道标识符
- read
函数原型:Error_T read(char * buf, size_t size,size_t& res)
函数功能:读取一次
参数说明:buf:存放输入数据的地址;size:缓冲区大小;res: 读取到的字节数
返回值:错误码
- write
函数原型:Error_T write(const char* buf, size_t size)
函数功能:同步写
参数说明:buf:存放输出数据的地址;size:输出的字节数
返回值:错误码
- asyncWrite
函数原型:void asyncWrite(const char* buf, size_t size, WriteHandler_T whenDone)
函数功能:异步写
参数说明:buf:输出数据的首地址;size:数据长度;whenDone:回调函数。
返回值:无
- intRead
函数原型:void intRead(const IntRead_T& hdl)
函数功能:中断读
参数说明:hdl:回调函数,函数返回值表示“是否继续接收”,true继续,false停止
返回值:无
-
-
- RapidIO接口
- 使用方法及范例
- RapidIO接口
-
在ETest系统中,RapidIO接口操作主要由RapidIO_T
类型完成。
在使用Etest进行仿真模型设计和设备规划过程中,可以建立RapidIO通道,并且配置参数。当通道建立完成并且参数配置完成后,系统运行环境会自动创建RapidIO_T
类型的通道,名称和在“仿真模型”中建立的通道名称一致。在实时脚本中,即可直接使用该对象,进行数据的读/写操作。
-
-
-
- RapidIO_T类
-
-
类所在命名空间:Kiyun::LowerComputer::Rasl::Device
- className
函数原型:static const std::string& className()
函数功能:获取板卡标识
参数说明:无
返回值:板卡类型标识符
- get
函数原型:static RapidIO_T get(int id)
函数功能:获取RapidIO板卡对象
参数说明:id:板卡标识号
返回值:RapidIO板卡对象
- get
函数原型:static Channel_T get(const Setup_T& cfg)
函数功能:获取RapidIO板卡的一个通道对象
参数说明:cfg:板卡初始化结构
返回值:SRIO通道对象
- getChannel
函数原型:Channel_T getChannel(const Channel_T::Setup_T& cfg)
函数功能:获取系统中RapidIO板卡的一个通道对象
参数说明:cfg:板卡初始化结构
返回值:SRIO通道对象
- isValid
函数原型:bool isValid() const
函数功能:检查RapidIO板卡对象是否有效(建议使用前判断合法性)
参数说明:无
返回值:true:板卡有效,fasle:板卡无效
-
-
-
- Channel_T(SRIO通道)
-
-
- setup
参数类型 | 可选值 | 默认值 |
设备标识 (deviceID) | 16位无符号整数 | 0 |
- isValid
函数原型:bool isValid() const(强烈建议使用前判断通道合法性)
函数功能:检测通道是否有效
参数说明:无
返回值:true:通道有效,fasle:通道无效
- path
函数原型:Path_T path() const
函数功能:获取通道标识
参数说明:无
返回值:通道标识符
- asyncWrite
函数原型:void asyncWrite(const Frame_T& frame, WriteHandler_T whenDone)
函数功能:仅支持发送NWriteResp报文
参数说明:frame 为SRIO报文结构体,whenDone 收到响应的报文的回调函数
返回值:无
- intRead
函数原型:void intRead(const IntRead_T& hdl)
函数功能:注册总的报文处理回调函数,需根据报文不同类型分开处理
参数说明:回调函数 IntRead_T hdl = bool(const uint8_t* package,size_t size,Error_T err)
1.函数返回值表示“报文是否已处理”,true已处理,false未处理
2. package需要根据不用的类型解析包,包头(8字节)+ 数据(0-256)
3.size表示package的字节长度,err表示错误码(未使用)
返回值:无
- read
函数原型:Error_T read(Frame_T& frame)
函数功能:发送NREAD报文,并且等待数据返回
参数说明:frame 为SRIO报文结构体,需要指定目地器件ID(frame.i_dest) 、数据长度(frame.i_len)、数据在目地器件存储器中的地址(frame.i_addr)
返回值:错误码,0表示成功,其他则表示有出错
- write
函数原型:Error_T write(const Frame_T& frame)
函数功能:支持发送SRIO所有报文格式(NWRITE、SWRITE 、NWRITER、DOORBELL、RESPND、RESPWD等等)
参数说明:frame 为SRIO报文结构体,需要指定目地器件ID(frame.i_dest) 、数据长度(frame.i_len)、数据在目地器件存储器中的地址(frame.i_addr) 、数据(frame.i_data 0-256)
返回值:错误码,0表示成功,其他则表示有出错
-
- 操作系统相关服务
ETest 提供了 Task_T Semaphore_T Mutex_T Counter_T
等类以提供操作系统相关的服务,可以实现任务调度与协同。
-
-
- Task_T类
-
所在命名空间为:Kiyun::LowerComputer::Rasl::Os
。这个类的对象代表在下位机中运行的任务。
/** 系统固定头文件 */ |
spawn
方法
函数原型:std::pair<Task_T, Error_T> spawn(const SimpleEntry_T& ent)
参数:ent:型如 int (void*)
的函数。其参数忽略即可,正常情况应返回 0。
返回值:一个 pair
对象,first
成员是启动的 Task_T
对象,second
成员是错误情况。大多数情况下,second
成员可以安全的忽略。
wait
方法
函数原型:void wait();
函数功能:等待任务结束。调用者任务本身阻塞,直到所 wait
的任务退出才继续运行。必须在 spawn
所返回的 Task_T
对象上使用。
waitFor
方法
函数原型:
Mince::LowerComputer::Rasl::Error_T waitFor( Mince::LowerComputer::Rasl::Frame::Timeout_T t ); |
函数功能:等待任务结束或超时。调用者任务本身阻塞,直到所 wait 的任务退出或者超出指定的时间才继续运行。必须在 spawn 所返回的 Task_T 对象上使用。
auto task = Task_T::spawn(someFunction); auto err = task.waitFor(5_s); if(err) KYLOG(WARN) << "任务在指定时间内未结束!"; |
所在命名空间为:Kiyun::LowerComputer::Rasl::Os
。
- 构造方法
函数原型:Semaphore_T()
notifyOne
函数原型:void notifyOne()
函数功能:发送一个信号量,通知正在等待信号量的第一个线程继续执行。
notifyAll
函数原型:void notifyAll()
wait
函数原型:void wait()
函数功能:等待信号量。执行此方法的任务立即阻塞,直到其它任务在此信号量上调用 notify
为止。
waitFor
函数原型:bool waitFor(Kiyun::LowerComputer::Rasl::Frame::Timeout_T time)
函数功能:等待信号量的到来,最长等待时间为time,单位为秒。
-
-
- Mutex_T类
-
所在命名空间为:Kiyun::LowerComputer::Rasl::Os
。这个类用作互斥锁,通常用于保护那些“不可同时访问的资源”。
#include <Rasl/rasl.hpp> namespace { using namespace std; using namespace Kiyun::LowerComputer; using namespace Rasl::Frame;
using Rasl::Os::Task_T; using Rasl::Os::Mutex_T;
int x = 0; Mutex_T xMut; int adder(void*) { KYLOG_SCOPE("add"); xMut.lock(); for(int i = 0; i < 100000; ++i) ++x; xMut.unlock(); KYLOG(INFO) << "加完"; return 0; } } int kiyunMain() { KYLOG_SCOPE("main");
vector<Task_T> tasks; for(int i = 0; i < 200; ++i) { tasks.push_back(Task_T::spawn(adder).first); } for(auto t : tasks) t.wait();
KYLOG(INFO) << "x : " << x; return 0; } |
lock
方法
函数原型:void lock();
函数功能:取得锁。如果锁已被其它任务取得,则任务立即阻塞,直到锁被释放为止。如果锁已被本任务取得,再次调用 lock,后果未定义。
unlock
方法
函数原型:void unlock();
tryLock
方法
函数原型:bool tryLock();
函数功能:取得锁。如果锁已被其它任务取得,则返回 false,否则返回 true。如果锁已被本任务取得,再次调用本方法,后果未定义。
Guard_T
内嵌类
其构造函数以一个 Mutex_T
对象为参数,并在构造时调用其 lock
方法。在析构时调用对应 Mutex_T
对象的 unlock
方法。
std::queue<命令_T> 队列; Mutex_T 队列锁; void 入列(const 命令_T& cmd) { MCLOG_SCOPE("入列"); { // 用花括号划定锁的保护范围 Mutex_T::Guard_T guard{队列锁}; 队列.push(cmd); } // guard 对象在此之前析构,这里不再是锁的保护范围 MCLOG(INFO) << "命令已入列。"; } |
-
-
-
Counter_T
类
-
-
所在命名空间为:Kiyun::LowerComputer::Rasl::Os
。这个类用作计数器,用于“生产者与消费者”模式时,给资源计数。在多个生产者和/或多个消费者的场合,计数器能够保证资源计数的正确性。
#include <Rasl/rasl.hpp> #include <queue> namespace { using namespace std; using namespace Kiyun::LowerComputer; using namespace Rasl::Frame; using Rasl::Error_T; using Rasl::Device::Com_T; using Rasl::Os::Task_T; using Rasl::Logging_T; auto com00 = Com_T::get(Com_T::Setup_T("com/0/0") .baudRate(115200) .parity(Com_T::Parity_E::NONE_e) ); auto com01 = Com_T::get(Com_T::Setup_T("com/0/1") .baudRate(115200) .parity(Com_T::Parity_E::NONE_e) ); auto com02 = Com_T::get(Com_T::Setup_T("com/0/2") .baudRate(115200) .parity(Com_T::Parity_E::NONE_e) ); queue<string> que; Rasl::Os::Mutex_T bufMut; Rasl::Os::Counter_T readDone;
struct Reader_T { string rs; bool operator() (char* buf, size_t size, Error_T) { rs += string{buf, buf + size}; auto done = rs.size() >= 7; if(done) { { Rasl::Os::Mutex_T::Guard_T guard(bufMut); que.emplace(move(rs)); } readDone.count(); } return true; } }; } int kiyunMain() { KYLOG_GLOBAL().severity(Logging_T::Severity_E::INFO_e); KYLOG_SCOPE("main"); Reader_T reader0, reader1, reader2; com00.intRead(reader0); com01.intRead(reader1); com02.intRead(reader2); // 10秒钟没有输入则退出 while(readDone.waitFor(10_s)) { string rs = que.front(); que.pop(); KYLOG(INFO) << rs; } return 0; } |
count
方法
函数原型:void count();
函数功能:使资源计数加1。应当由“生产者”调用,表示可供“消费者”使用的资源多了一个。
countAll
方法
函数原型:void countAll();
函数功能:应当由“生产者”调用。满足当前所有等待资源的“消费者”。
wait
方法
函数原型:void wait();
函数功能:使资源计数减1。应当由“消费者”调用,如果当前资源计数为0,则当前任务立即阻塞,直到有“生产者”将资源计数增加为止。
waitFor
方法
函数原型:bool waitFor(Mince::LowerComputer::Rasl::Frame::Timeout_T);
函数功能:使资源计数减1或者超时。应当由“消费者”调用,如果当前可用资源计数为0,则当前任务立即阻塞,直到有“生产者”增加资源计数或超时为止。
Etest实时脚本API提供了Frequency_T、Period_T、Ticker_T和 Timer_T等类,以便进行与时序有关的操作。
创建周期性触发的系统时钟使用Ticker_T类型。可以先创建一个Ticker_T对象,指定其触发周期,然后使用Start方法启动定时器,在启动的时候给出的参数为每次时钟周期到时被调用的函数。最后可以使用stop方法停止定时器。如以下范例:
#define MC_APPNAME "TickerTest" // 自动用作输出前缀 #include <Rasl/rasl.hpp> #include "rasl-dpd/user.hpp" #include "UserChannels.rasi" namespace { using namespace Kiyun::LowerComputer::Rasl::Frame; using namespace std; } int kiyunMain() { KYIO(log) << "Setting ..."; unsigned mtCount = 0; Ticker_T ticker1 = Ticker_T::get(2.0_s); // 2.0 秒,指定周期值 Ticker_T ticker2 = Ticker_T::get(0.8_hz); // 0.8 赫兹,指定频率值 Ticker_T ticker3 = Ticker_T::get(0.8); // Ticker 默认接受频率值 auto ticker4 = Ticker_T::get(10_hz); ticker1.start([]() -> bool { KYIO(out) << " =-+---- 2.0 seconds "; return true; }); ticker2.start([]() -> bool { KYIO(out) << " =-+---- 0.8 herz"; return true; }); ticker3.start([]() -> bool { KYIO(out) << " =-+---- 0.8"; return true; }); // ticker4.start([&mtCount]{ ++mtCount; return true; }); KYIO(log) << "Fired ..."; Timer_T::delay(5.0); // Timer 默认接受时长(周期),5秒后停止时钟 KYIO(out) << "Ticker count : " << mtCount; ticker1.stop(); ticker2.stop(); ticker3.stop(); ticker4.stop(); return 0; } |
创建一次性的系统延时可以使用Timer_T类型的delay方法。
使用方法为:
Timer_T::delay(5.0); // Timer 结束时长(单位为秒) |
-
-
- Frequency_T类与 Period_T 类
-
所在命名空间:Kiyun::LowerComputer::Rasl::Frame
。
这两个类分别代表 频率 与 周期(时长)。其中 Period_T 有别名为 Timeout_T(时长)。
- 构造函数
函数原型:
Frequency_T(float);
Period_T(float);
参数:step:频率(以赫兹为单位)或周期(以秒为单位)的浮点值。
- 自定义字面量
_hz 后缀可构造 Frequency_T 的对象;_s 后缀可构造 Period_T 的对象。如:
Frequency_T 频率 = 0.5_hz; Period_T 周期 = 1e-3_s; // 1毫秒 |
- 算术运算
Frequency_T 和 Period_T 对象支持带量纲的算术运算。如下所示:
auto f1 = 0.5_hz * 2; // => 1_hz f1 = f1 / 2.0; // => 0.5_hz auto t1 = 1.0 / 0.5_hz; // => 2_s float res = 2.0_hz * 4_s; // => 8.0 (无量纲) t1 = 10_s - 5_s; // => 5_s t1 = 5_s + 5_s; // => 10_s t1 = 1_s * 0.1; // => 0.1_s f1 = 1.0 / t1; // => 10_hz |
注意:Frequency_T 对象不支持加减运算,因为其物理意义不明确。
各算术运算对应的赋值操作是支持的。如:
auto f1 = 0.5_hz * 2; // => 1_hz f1 /= 2; // => 0.5_hz |
-
-
- Ticker_T类
-
所在命名空间:Kiyun::LowerComputer::Rasl::Frame
。
get
方法一
函数原型:static Ticker_T get(Step_t&& step)
typedef std::function<unsigned(unsigned)> Step_T;
注意 Frequency_T 和 Timer_T 类的对象均符合这一定义。
- get方法二
函数原型:static Ticker_T get(const Step_t& step)
- get方法三
函数原型:static Ticker_T get(Frequency_T freq)
- start方法
函数原型:void start(Listener_T&& hdl)
typedef std::function<bool()> Listener_T;
- stop方法
函数原型:void stop()
实现系统延时功能。
- delay方法
函数原型:static void delay(Timeout_T t);
- make方法
函数原型:static Timer_T make(Timeout_T t, Listener_T&& lis);
参数:lis:延时到达后调用的回调函数。其原型为:void(Timer_T)
返回值:Timer_T 对象,可供调用 cancel 方法。
- cancel方法
此方法只能在 make 方法的返回值对象上调用,取消定时器。
- restart方法
此方法只能在 make 方法的返回值对象上调用,定时器将重新开始计时。
-
- 基础服务
本章节介绍在实时脚本语言中提供的基本输出与日志功能。
MC_APPNAME 宏:这个宏定义当前模块的名称。如果没有这个宏,那么会以模块的文件名作为名称。这个名称会出现在基本输出和日志输出中。
-
-
- 基本输出
-
提供标准错误、标准输出和标准日志三个流,可以通过 KYIO(err)、KYIO(out)和KYIO(log) 来使用。支持基本类型的流出操作,如下所示:
#define MC_APPNAME "TestApp" // 在屏幕上显示 ERR | TestApp | write timeout : 10 KYIO(err) << "write timeout : " << 10; size_t size = 100; // 在屏幕上显示 INF | TestApp | write done : 100 KYIO(out) << "write done : " << size; const char name = 'c'; // 在屏幕上显示 LOG | TestApp | write done : com KYIO(log) << "write done : " << name; |
-
-
- 日志使用方法
-
下位机程序中输出的日志会显示在上位机日志查看器中。
以下代码均假定引入了命名空间:
using namespace std; using namespace Kiyun::LowerComputer; using namespace Rasl; |
在下位机程序中有五个宏可用:
1、KYLOG_GLOBAL 用来设置全局属性,一般用在程序入口处。如:
KYLOG_GLOBAL().severity(Logging_T::Severity_E::NOTI_e); |
上面的代码,指定全局过滤级别为“通知”,即只发送通知以上(含)级别的消息。级别有 TRAC_e, DEBG_e, INFO_e, NOTI_e, WARN_e, ERRO_e, NONE_e。其中 NONE_e 留作系统消息,不要使用。
2、KYLOG_SCOPE 用来设置局部属性,用在函数或作用域开头。
KYLOG_SCOPE("类名::方法名").tag("发送").tag("检查"); |
上面的代码设置当前 scope 为 "类名::方法名",这个名字是任意的,建议就用函数名,它会记录为调用堆栈。为当前 scope 内的所有日志消息加了“发送”和“检查”两个标签。标签是任意的,用来在上位机调试器中过滤日志消息,以聚焦于关心的方面。
3、KYLOG 用来输出日志。
KYLOG_SCOPE("类名::方法名"); // ... 其它代码 KYLOG(INFO) << "消息码(16进制): " << hex << setw(sizeof(x) * 2) << setfill('0') << x; |
其中 INFO 指定本条日志的级别为 INFO_e,注意 _e 后缀不必写。
如果 x 是 int 类型值为 20,输出将是: 消息码(16进制) : 00000014。
如果 x 是 short 类型值为 20,输出将是: 消息码(16进制) : 0014。
KYLOG 支持所有流操作符和流类型。
4、为单个日志添加标签:
- KYLOG_DEF 与 KYLOG_USE 宏
KYLOG_DEF(NOTI).tag("信号处理相关").tag("发送相关"); KYLOG_USE() << "日志内容"; |
这两个宏必须连在一起,中间不能有任何其它代码。这种方式可以为单条日志加 tag,以便在日志查看器中过滤。
注意: `KYLOG(WARN)` 其实相当于 `KYLOG_DEF(WARN);KYLOG_USE()。
- 进阶用法
日志器对外表现为一个标准的输出流,符合 std::ostream 接口要求,可以使用 C++流的格式化与设置等功能。示例如下:
void formatMask(uint32_t mask) { KYLOG_SCOPE("formatExample"); KYLOG(INFO) << "掩码为 : 0x" << setw(8) // 宽度为8 << setfill('0') // 宽度不足部分填 0 << hex // 16进制显示 << mask; } formatMask(100); // 在日志查看器中显示: 掩码为 : 0x00000064 |
本章节介绍在实时脚本语言中使用协议的方法。
用户在Etest仿真模型中建立的接口协议描述,在实时脚本中可以作为类型使用,进行原始数据的解包和组包。
如:将某通道中协议名声明为“信号协议”;在编译后,Etest环境会生成一个名为“信号协议_T”的C++类,可供使用。该类所在命名空间为:Kiyun::LowerComputer::Dpdp
(注:目前暂不支持协议中的分支定义与自定义长度整形的定义。)
以协议“信号协议”为例进行说明:
类名:信号协议
_T
构造函数:信号协议
_T
auto 协议包 = 数据协议_T(); |
属性访问方法:
协议中的每一个字段都可以按名称访问。比如声明了如下DPD:
|
会生成类Kiyun::LowerComputer::Rasl::Dpdp::
信号协议
_T
。
auto 信号 = 信号协议_T().发送时间(0).采集时间(0).信号幅值(0); |
auto 信号 = 信号协议_T(); 信号.发送时间(66); 信号.采集时间(55); 信号.信号幅值(5); |
uint32_t sendEpoch = 信号.发送时间(); float amplitude = 信号.信号赋值(); |
函数原型:FeedResult_T feed(uint8_t food)
feed
方法返回一个FeedResult_T
对象,具有good
和done
两个bool
属性,分别表示“正确”与“完整”。另一个errPos
属性,在“不正确”的情况下指明协议的错误位置,单位为字节。
for(auto c:buf){ auto 解析结果 = 协议包.feed(c); if(!解析结果.good){ //错误处理 } else if(解析结果.done) { //数据包已经完整 //....使用 协议包.clear(); //清零,可以重新feed } } |
fromBuffer
函数原型:FeedResult_T fromBuffer(const Buffer_T& buf)
Buffer_T buf; //buf为std::vector<uint8_t>的别名 auto 解析结果 = 协议包.fromBuffer(buf); |
spit
函数原型:SpitResult_T spit()
SpitRes_T 输出结果; do { 输出结果 = 协议包.spit(); char c = 输出结果.res; // 处理 c } while(!输出结果.done); // 到完成为止 |
toBuffer
函数原型:bool toBuffer(Buffer_T& buf)
参数:buf:std::vector<uint8_t>
的别名,存放从协议包解析出的数据
Buffer_T buf; bool 成功 = 协议包.toBuffer(buf); if(!成功) { //错误处理 } |
-
- 应用支持-数据上传
数据上传将测试数据从下位机上传到上位机,上位机的数据中心负责测试数据的保存,并转发到监控界面。
数据上传的数据内容和数量由用户在实时脚本中决定。用户使用数据上传接口,将数据上传到上位机;
数据上传操作由数据上传服务完成。数据上传服务作为一个后台进程在下位机运行。数据上传服务的优先级比较低,会在系统不繁忙的时候运行,不会抢占系统资源。
本章节介绍在实时脚本语言中将数据上传的方法。
数据上传操作主要包括两个步骤:1、创建UploadService_T
类型的对象“上传通道”;2、将数据入队列等待上传。
如:执行如下代码,则表示将“输出”通道输出的读数据上传。
auto 上传通道 = Channel_T::get( 输出.path(), Channel_T::Direction_E::READ_e ); //buf 类型为 vector<char>,包含需要上传的数据 auto data = DataUploader::Data_T{上传通道, 0, buf}; UploadService_T::get().queue(data); |
注意:创建“上传通道”的时候,使用了“输出”通道,因此数据上传时被标记为是“输出”通道的数据;在“实时数据”工具的“调用者”栏会显示为“输出”通道。
所在命名空间为:Kiyun::LowerComputer::DataUploader
。
get
函数
初始化一个Channel_T
对象
函数原型:static Channel_T get(const std::string& device, Direction_E direction)
参数:device:设备名;direction:模式(读/写)
返回值:Channel_T对象
说明:对于同设备名同方向的通道,这个方法会取得同一个对象,不会重复创建。
device
函数
获取设备名称
函数原型:const std::string& device() const
参数:无
返回值:设备名称
direction
函数
获取设备的读写模式
函数原型:Direction_E direction() const
参数:无
返回值:读写模式
构造Data_T
结构体
原型:
Data_T( Channel_T channel, uint64_t time, // 时间为0表示当前时刻,相当于 Data_T::now() std::vector<char>&& content ); |
参数:channel:通道;time:时间戳;content:数据内容。
函数原型:static UploadService_T get()
get
函数2
函数原型:static UploadService_T get(const std::string& addr)
isValid
函数
函数原型:bool isValid()
- queue函数
函数原型:void queue(Data_T data)
上传服务对象可以直接取得,通道对象和数据对象都可以当场构造。另外,Data_T 对象提供了可变参数的构造函数,提供了语法上的额外便利。所以,上传代码可以这样写:
uint32_t 操作码 = 12345678; uint16_t 数据头 = 0x0A05; vector<char> 数据 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; uint32_t 数据尾 = 0x050A050A; UploadService_T::get().queue({ // 花括号隐式构造一个 Data_T 对象 Channel_T::get(com.path(), Channel_T::Direction_E::WRITE_e), 0, // 当前时间 操作码, 数据头, 数据, 数据尾, (int32_t)0, (uint8_t)10 }); |
注意:为了准确控制上传数据的字节数,要非常明确的指定数据的类型。比如在数据尾之后上传的0和10,做了强制类型转换,否则它们的长度由编译器决定,不一定是想要的结果。
-
- 应用支持-数据采集方案
数据采集API配合ETest数据采集方案进行使用。在进行测试设计时,完成仿真模型中的接口类型和协议的设计之后,可以在PC规划界面添加VX类型的客户端,然后在该客户端进行“数据采集方案”的配置;同时,在下位机脚本中使用类似“外围系统.read(协议对象)”或者“外围系统.write(协议对象)”的方式进行接口数据的存取,则ETest环境自动生成代码,将数据采集方案中勾选的数据协议字段进行上传到上位机,可以在上位机工具的“实时数据查看”工具中进行查看,也可以在“历史数据查看”工具中进行查看和分析。
-
-
- 使用方法简介
-
例如:某个测试方案中进行仿真模型设计如下图所示。
- 5 ETest仿真模型举例
PC规划中的数据采集方案设计如下图所示:
- 6 数据采集方案举例
可以创建实时任务,内容如下所示:
外围系统_2 outSys; //初始化一个外围系统对象 //协议对象初始化,注意为” Protocol_5_T()”和” Protocol_2_T()”相比ETest界面//多了字符”_T” auto pro5 = Protocol_5_T().发送时间(1).采集时间(0).信号幅值(0.5); auto pro2 = Protocol_2_T(); if(!outSys.write(pro5)){ KYIO(err) << "Data Collect Protocol_5_T failed."; return -1; } Timer_T::delay(1); if(!outSys.read(pro2)){ KYIO(err) << "Data Collect Protocol_2_T failed."; return -1; } |
说明:
系统自动生成名称同外围系统名称一样的类型“外围系统_2”;
外围系统outSys有如下四个接口可供调用:
outSys.write(Protocol_5_T);
outSys.read(Protocol_5_T);
outSys.write(Protocol_2_T);
outSys.read(Protocol_2_T);
即对于每一个协议类会有一个write和read接口,且接口的返回值为bool型变量。但对AD和DO接口,只有read接口可用;对DA和DI接口,只有write接口可用。
AD通道有两个read接口可供调用:
read(协议类型); //AD单次采集
read(协议类型, int); //AD连续采集,第二个参数表示采集频率为250K时采集的时间长度(以秒钟为单位);
另外需要在源文件中包含头文件: #include "DataCollect.hpp"
引入命名空间:using namespace Kiyun::DataCollect;
-
-
- 范例
-
如下:
#define MC_APPNAME "2COM_TEST" /** 系统固定头文件 */ #include <Rasl/rasl.hpp> #include <DataUploader/DataUploader.hpp> #include "rasl-dpd/user.hpp" #include "UserChannels.rasi" #include "DataCollect.hpp" #include <boost/circular_buffer.hpp> namespace { using namespace std; using namespace Kiyun::LowerComputer; using namespace Kiyun::LowerComputer::Rasl; using namespace Kiyun::LowerComputer::Rasl::Frame; using namespace Kiyun::LowerComputer::Rasl::Device; using namespace Kiyun::LowerComputer::DataUploader; using namespace Kiyun::Channel; using namespace Kiyun::DataCollect; using namespace Dpdp; void f_sync_wr(); //串口"发送端(com/0/0)"同步写数据,串口"接收端(com/0/1)同步读数据" } int Main(){ KYIO(out) << "Hello, COM!"; if(!发送端.isValid() || !接收端.isValid()){ KYIO(err) << "Channel is invalid, please check!!!"; return -1; } f_sync_wr(); return 0; } namespace { void f_sync_wr(){
外围系统_2 outSys; auto pro5 = Protocol_5_T().发送时间(1).采集时间(0).信号幅值(0.5); auto pro2 = Protocol_2_T(); int times=25; while (times >0){ //同步写测试 if(!outSys.write(pro5)){ KYIO(err) << "Data Collect Protocol_5_T failed."; return; } Timer_T::delay(1); if(!outSys.read(pro2)){ KYIO(err) << "Data Collect Protocol_2_T failed."; return; } times--; } } } |
-
-
- 模型间通信数据采集
-
模型间通信的数据采集和接口的数据采集API的使用方法一样。只需在ETest的模型间通信的采集方法配置界面进行配置。
首先进行模型间通信的通道和协议配置。
- 7 模型间通信通道配置
然后进行采集方案的配置。如图所示。
- 8 模型间通信采集配置
最后编写实时脚本,进行数据收发和上传。
//初始化两个外围系统对象 外围系统_1 outSys_1; 外围系统_3 outSys_3; //协议对象初始化 auto pro = Protocol_外围系统_1_1_T(); if(!outSys_1.write(pro)){ KYIO(err) << "Data Collect Protocol_外围系统_1_1_T failed."; return; } Timer_T::delay(1); if(!outSys_3.read(pro)){ KYIO(err) << "Data Collect Protocol_外围系统_1_1_T failed."; return; } |
-
- 应用支持-实时参数设置
对于一些仿真任务,可以在运行中让用户修改一些运行参数,调整任务的运行状态。对于这种任务,可以使用“实时参数设置”功能。
实时参数设置支持在实时任务运行过程中,使用ETest中的“实时参数调节”工具修改任务内部变量的值。本节介绍此功能的使用方法。
- 首先设计一个实时任务,任务需要运行一段时间,其中用到若干参数(变量)。
- 将需要调节的变量定义为全局变量。
- 设计
kiyunParameterSet
函数,函数内部可以进行必要的检查等操作。该函数在变量被修改之前和之后都会被调用一次。 - 运行该实时任务。
- 使用Etest的工具“实时参数调节”,打开实时任务,显示可以调节的变量。给出希望修改的变量值,点击“发送”修改变量值。
实时任务如以下范例所示。
#define MC_APPNAME "SETP-TEST" #include <Rasl/rasl.hpp> #include "rasl-dpd/user.hpp" #include "UserChannels.rasi" namespace { using namespace std; using namespace Kiyun::LowerComputer::Rasl; using namespace Kiyun::LowerComputer::Rasl::Frame; Os::Semaphore_T f_终止信号; } namespace Kiyun { namespace LowerComputer { namespace Rasl { namespace Test { char g_字符 = 'a'; short g_短整 = 256; int g_整数 = 70000; long g_长整 = 100; long long g_大整 = 200; float g_浮点 = 0.1; double g_双精; }}}} unsigned char g_u字符 = 100; unsigned short g_u短整; unsigned int g_u整数; unsigned long g_u长整; unsigned long long g_u大整; string g_字符串 = "abcdefg"; Frequency_T g_频率 = 1.5_hz; Timeout_T g_时长 = 0.5_s; int kiyunMain() { f_终止信号.wait(); // 等待信号退出 return 0; } extern "C" bool kiyunParameterSet(bool beforeSet, void* paramAddr, const string& value) { using namespace Kiyun::LowerComputer::Rasl::Test; if(beforeSet) KYIO(log) << "Set values,not check: " << paramAddr << " => " << value; else { if(false) {} #define WATCH_VALUE(n) \ else if(&g_##n == paramAddr) \ KYIO(out) << #n "新值 : " << g_##n; WATCH_VALUE(字符) WATCH_VALUE(短整) WATCH_VALUE(整数) WATCH_VALUE(长整) WATCH_VALUE(大整) WATCH_VALUE(u字符) WATCH_VALUE(u短整) WATCH_VALUE(u整数) WATCH_VALUE(u长整) WATCH_VALUE(u大整) WATCH_VALUE(字符串) WATCH_VALUE(频率) WATCH_VALUE(时长) } if(g_字符串 == "exit") // 字符串值修改为 exit 表示退出 f_终止信号.notifyOne(); return true; } |
-
-
- 支持的数据类型
-
所有C数值类型(整型、浮点);
RASL运行库中的频率(Kiyun::LowerComputer::Rasl::Frame::Frequency_T
);
周期类型(Kiyun::LowerComputer::Rasl::Frame::Period_T
);
C++ STL 字符串;
实时参数设置支持用户自定义的全局变量(不包括匿名空间(namespace)中的变量)值的修改。如范例中所示,支持修改所有全局变量,包括在命名空间中的全局变量,也支持类的静态变量。
注意:在匿名命名空间中的变量不是全局变量,不支持调参。
该实时任务中可以包含”kiyunParameterSet
” 函数,如范例中所示,调参功能会在每个变量设置前、设置后分别调用一次”kiyunParameterSet
” 函数。在变量设置前以’beforeSet’
为’true’
调用,在变量设置完成后以’beforeSet’
为’false’
调用。在变量设置前,如果 kiyunParameterSet
函数返回 false
,表示“不允许设置参数”,则参数不变。否则参数被设置为指定的值。
如果实时任务中没有kiyunParameterSet
函数,则直接设置参数。
支持’int64_t
’和’uint64_t
’,但取值范围依然只是32位;
支持128位’long double
’,但取值范围依然只是64位;
-
- 应用支持-内容附件使用
ETest实时API提供方法能够对ETest项目文件中的“内容附件”进行使用。本节介绍这些数据的使用方法。
-
-
- 使用方法及范例
-
ETest使用内容附件的API主要包括两个类:DataStore_T和DataLine_T。
首先使用DataLine_T获取内容附件对象,然后读取里面的数据按需使用。
范例如下:
/** 系统固定头文件 */ |
-
-
- DataStore_T
-
代表一个内容附件对象。所属命名空间为Kiyun::LowerComputer::Rasl::Data。
1) get函数
函数原型: static DataStore_T get(const char * file)
函数功能:获取数据文件的容器
参数说明:file:数据文件名
返回值:文件容器对象
2) setPath函数
函数原型: static void setPath(const char * path)
函数功能:设置FTP相对文件路径(默认为userData,即FTP根目录下的userData目录)
参数说明:path:相对路径
返回值: 无
注:一般无需设置,如需自定义路径,则setPath需在导入数据文件之前进行调用,否则自定义路径将无法生效。
3) getNextLine函数
函数原型:const char * getNextLine()
函数功能:从文件容器中获取一行字符串
参数说明:无
返回值:字符串指针,为NULL则表示读到文件尾。
4) getNextBlock函数
函数原型:std::vector<char> getNextBlock(size_t blockLen = cc_maxBlock)
函数功能:从文件容器中获取一个字节块
参数说明:blockLen:字节块大小,默认字节块大小cc_maxBlock = 4M
返回值:字节容器,容器size为0则表示读到文件尾。
5) begin函数
函数原型:Iterator_T begin()
函数功能:返回一个当前容器中起始行的迭代器
参数说明:无
返回值:行迭代器
6) end函数
函数原型:Iterator_T end()
函数功能:返回一个当前容器中末尾行的迭代器
参数说明:path:相对路径
返回值:行迭代器
-
-
- DataLine_T
-
代表一个内容附件中的一行数据。所属命名空间为Kiyun::LowerComputer::Rasl::Data。
1) c_str
函数原型:const char* c_str() const
函数功能:获取当前行的字符串指针
参数说明:无
返回值:字符串指针
2) at
函数原型:const char* at(int index)const
函数功能:返回当前行的指定逗号分割字符串指针
参数说明:列序列号
返回值:字符串指针
3) size
函数原型:size_t size() const
函数功能:返回当前行所包含的列数
参数说明: 无
返回值:总共包含的列数
4) length
函数原型:size_t length() const
函数功能:返回当前行所包含的字符个数
参数说明: 无
返回值:字符个数
5) empty
函数原型:bool empty() const
函数功能:是否为空行
参数说明: 无
返回值:true:空行,false:不为空行
6) get
函数原型:template<typename T> T get(int index = 0) const
函数功能:获取列并进行格式化转换
参数说明: 列序列号,默认为0
返回值:列元素
注:可转换成如下类型:
有(无)符号整形,浮点型,string,char,char *,const char* ,vector<char>
7) get<vector<char>>
函数原型:template<> vector<char> get(int index = 0) const
函数功能:获取列并可将hex字符串转换成buf
参数说明: 列序列号,默认为0
返回值:列元素的buf
注:可将hex字符串转换成字节流,字符串必须以0x或者0X开头,如0x010203,否则将不会对字符串进行hex转换。
-
- 通用类型
Etest实时脚本中的API中共同用到了一些类型,在此对这样类型进行详细介绍。
Path_T
类型所属命名空间为:Kiyun::LowerComputer::Rasl::Device
类型定义为:
namespace Mince { namespace LowerComputer { namespace Rasl { namespace Device { struct Path_T { inline Path_T(const char* pathStr) : Path_T(std::string(pathStr)) {} Path_T(std::string&& pathStr); Path_T(const std::string& pathStr); Path_T(const std::string& className, int cardId, int channelId); Path_T(const std::string& className, int channelId); const std::string className() const noexcept; const std::string path() const noexcept; int cardId() const noexcept; // 返回 -1 表示没有 int channelId() const noexcept; // 返回 -1 表示没有 inline operator std::string () const { return i_path; } std::string i_path; }; }}}} |
Error_T
类型所属命名空间为:Kiyun::LowerComputer::Rasl
类型定义为:
typedef boost::system::error_code Error_T; |
有关方法请查阅 boost 库参考手册。
这篇关于便携式航电实时系统测试平台实时脚本介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!