文章目录
- 前言
- Server接口
- 设计server接口
- Simulink实现server函数
- mapping Function
- 生成的代码
- Client接口
- 设计Client接口
- Simulink实现Client
- Function Caller Mapping
- 生成的代码
- Rte_Call
- Rte_Result
- 总结
前言
在之前的一篇文章中,介绍了RTE中的S/R接口,也是RTE中使用最多的接口。在Autosar定义的Interface中,分为Require Ports(需求接口,对应的S/R接口中的Receiver接口,C/S接口中的Client接口)和Provide Ports(提供接口,对应S/R接口中的Sender接口,C/S接口中的Server接口)。
S/R接口主要针对数据传输,而C/S接口主要是针对操作。一般C/S接口以函数调用和函数的形式存在。Client调用Server端的操作,一般以Runnable形式存在。
Server接口
对于Server接口来说,实际就是一个功能函数的实现,在Autosar中,大部分时候都是通过Client接口调用对应的Server的函数。
此处演示在Simulink中如何创建一个Server接口,其他RTE设计工具中也是类似的选项
设计server接口
创建好一个Autosar类型的Model后,Ctrl+Shift+C打开Autosar SW Component,然后打开Autosar Dictionary
通过C/S Interface创建一个接口名为TestCSIf_server,然后创建对应的Operation, Operation即为对应的操作名称,Operation后面会关联到Runnable上。
此处操作名称为TestFunc_server.
接着通过Arguments配置操作的参数,此处示例配置两个输入和一个输出
此处只是定义了部分函数原型,具体的实现需要在Simulink中做,或者生成代码后自己再手动在Runnable中编写。
创建好接口后,需要创建serverPorts
将之前创建的C/S Interface与ServerPort映射
然后创建server对应的runnable,此处函数名称为TestFunc_server
Runnable选择Event为OperationInvokedEvent,且选择Event Trigger为之前创建的server的Operation,进行了Operation与Runnable的映射。
Simulink实现server函数
使用Simulink Function实现函数,示例如下
可以在信号属性中设计输入输出的数据类型
mapping Function
在Autosar SW Component中的Function界面进行Runnable和Function的mapping
生成的代码
生成的代码中关于server,只有一个对应的Runnable函数。关于Interface和Port的信息,都在Arxml中体现。
/* Output function */
void TestFunc_server(uint8 Input1, uint8 Input2, uint8 *Output)
{
/* Outputs for Function Call SubSystem: '<Root>/Simulink Function' */
/* SignalConversion generated from: '<S1>/Output' incorporates:
* SignalConversion generated from: '<S1>/Input1'
* SignalConversion generated from: '<S1>/Input2'
* Sum: '<S1>/Add'
*/
*Output = (uint8)((uint32)Input1 + Input2);
/* End of Outputs for SubSystem: '<Root>/Simulink Function' */
}
实际使用中,将Client接口与Server接口正确连接后,Client即可调用对应的Server函数了。C/S接口的map需要在Autosar RTE设计工具中配置。
Client接口
标题中的synchronous和asynchronous都是针对Client接口的,表示调用Server的方式。在Simulink没有配置同步还是异步,默认都是同步。
此处演示在Simulink中如何创建一个Client接口
设计Client接口
和Server接口一样,创建Client Interface,名为TestCSIf_client,然后创建Operation,接着创建参数,示例如下:
然后创建Client Ports,如下所示:
此处接口就建立好了。
Simulink实现Client
在Simulink中的10ms的Runnable中使用Function Caller模块实现Client,示例如下:
Function Caller Mapping
将刚刚建立的Function Caller和之前创建的Client Port进行map
生成的代码
生成的代码其实就是在10ms的Runnable中调用Client接口,此处默认是同步调用,接口为Rte_Call类型
/* Model step function for TID1 */
void Runable_10ms(void) /* Explicit Task: Runnable_10ms */
{
uint8 rtb_FunctionCaller;
/* RootInportFunctionCallGenerator generated from: '<Root>/Runnable_10ms' incorporates:
* SubSystem: '<Root>/Subsystem'
*/
/* FunctionCaller: '<S2>/Function Caller' incorporates:
* Inport: '<Root>/In1'
* Inport: '<Root>/In2'
*/
Rte_Call_cPort_TestFunc_client(Rte_IRead_Runable_10ms_Input1_Val(),
Rte_IRead_Runable_10ms_Input2_Val(), &rtb_FunctionCaller);
/* End of Outputs for RootInportFunctionCallGenerator generated from: '<Root>/Runnable_10ms' */
/* Outport: '<Root>/Out1' */
Rte_IWrite_Runable_10ms_Output_Val(rtb_FunctionCaller);
}
实际使用中,大部分应该都是同步调用。
Rte_Call
该函数为标准中的API函数,原型如下:
Std_ReturnType
Rte_[Byps_]Call_<p>_<o>([IN Rte_Instance <instance>],
[IN|IN/OUT|OUT] <data_1>...
[IN|IN/OUT|OUT] <data_n>,
[OUT Std_TransformerError transformerError])
接口中<p>表示port名称,<o>表示operation名称,IN|IN/OUT|OUT表示输入输出参数,其他参数用的比较少。
假设Port名称为cPort,operation名称为TestFunc,则生成的Rte_Call接口名称示例如下:
Rte_Call_cPort_TestFunc
在同步通信中,输入和输出可以同时存在。而在异步通信中,调用Rte_Call时,输出参数应该被省略,需要使用Rte_Result来获取输出结果。
规范中解释如下:
在异步通信情况下:
•Rte_Call只包括IN和IN/OUT参数。
•Rte_Result只包含IN/OUT和OUT参数来收集服务器调用的结果。
•Rte_Call期间提供的IN/OUT参数可以是与Rte_Result期间传递的IN/OUT参数不同的地址。
标准中的同步通信过程:
实际Client调用Server时应该还有一个超时返回的功能,但是一般生成的代码中都没有体现(可能是我没有用对)
Rte_Result
该函数为标准中的API函数,原型如下:
Std_ReturnType
Rte_[Byps_]Result_<p>_<o>([IN Rte_Instance <instance>],
[IN/OUT|OUT <param 1>]...
[IN/OUT|OUT <param n>],
[OUT Std_TransformerError transformerError])
可以看出该函数中没有包含IN的参数,只有OUT或IN/OUT,也对应其名称Result,就是用来获取之前函数运行的结果的。
在异步通信中,Client调用Rte_Call函数后可以先返回,然后通过Rte_Result函数来获取结果
标准中的异步通信过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOCV0QLE-1687527971221)(null)]
异步通信主要可以提高运行效率。
CFG中配置异步通信:
Polling:循环读取结果
Waiting:设置一个等待时间,时间到了之后读取结果
None:配置为事件触发,server运行完后会触发该事件,以触发client的响应,读取结果
实际使用中,还没有使用过异步通信,可能描述的不一定准确。
总结
C/S接口一般在NVM或DEM中使用较多,SWC使用时一般都以Client的形式去调用BSW的API函数,后面有空会继续分享相关内容。