1. 创建第一个AUTOSAR AP服务
任务说明
本案例使用AUTOSAR AP工具链(以ara::com为核心)创建一个简单的服务接口ExampleService,该服务提供两个方法:Add(整数加法)与GetVersion(返回版本字符串),并生成对应的服务框架代码(服务端骨架与客户端代理)。最终交付物为:服务接口描述文件(ARXML)、由工具链生成的C++服务框架代码、以及一个最小可编译验证工程。
服务接口设计
服务接口采用AUTOSAR ARXML格式定义,包含两个方法、一个事件和一个属性。方法Add接收两个int32参数,返回int32结果;方法GetVersion无参数,返回String。事件CounterEvent周期性推送uint32计数器值;属性Status为可读写Boolean。接口命名空间为demo::soa。
ARXML服务接口定义
<?xml version="1.0" encoding="UTF-8"?>
<!-- ExampleService.arxml -->
<AUTOSAR xmlns="http://autosar.org/schema/r4.0">
<AR-PACKAGES>
<AR-PACKAGE>
<SHORT-NAME>demo</SHORT-NAME>
<AR-PACKAGES>
<AR-PACKAGE>
<SHORT-NAME>soa</SHORT-NAME>
<ELEMENTS>
<SERVICE-INTERFACE>
<SHORT-NAME>ExampleService</SHORT-NAME>
<NAMESPACES>
<NAMESPACE>
<SHORT-NAME>demo</SHORT-NAME>
<SHORT-NAME>soa</SHORT-NAME>
</NAMESPACE>
</NAMESPACES>
<METHODS>
<CLIENT-SERVER-OPERATION>
<SHORT-NAME>Add</SHORT-NAME>
<ARGUMENT>
<SHORT-NAME>left</SHORT-NAME>
<TYPE-TREF DEST="IMPLEMENTATION-DATA-TYPE">/DataType/Int32</TYPE-TREF>
<DIRECTION>IN</DIRECTION>
</ARGUMENT>
<ARGUMENT>
<SHORT-NAME>right</SHORT-NAME>
<TYPE-TREF DEST="IMPLEMENTATION-DATA-TYPE">/DataType/Int32</TYPE-TREF>
<DIRECTION>IN</DIRECTION>
</ARGUMENT>
<ARGUMENT>
<SHORT-NAME>result</SHORT-NAME>
<TYPE-TREF DEST="IMPLEMENTATION-DATA-TYPE">/DataType/Int32</TYPE-TREF>
<DIRECTION>OUT</DIRECTION>
</ARGUMENT>
</CLIENT-SERVER-OPERATION>
<CLIENT-SERVER-OPERATION>
<SHORT-NAME>GetVersion</SHORT-NAME>
<ARGUMENT>
<SHORT-NAME>version</SHORT-NAME>
<TYPE-TREF DEST="IMPLEMENTATION-DATA-TYPE">/DataType/String</TYPE-TREF>
<DIRECTION>OUT</DIRECTION>
</ARGUMENT>
</CLIENT-SERVER-OPERATION>
</METHODS>
<EVENTS>
<SEND-RECEIVE-EVENT>
<SHORT-NAME>CounterEvent</SHORT-NAME>
<TYPE-TREF DEST="IMPLEMENTATION-DATA-TYPE">/DataType/UInt32</TYPE-TREF>
</SEND-RECEIVE-EVENT>
</EVENTS>
<FIELDS>
<FIELD>
<SHORT-NAME>Status</SHORT-NAME>
<TYPE-TREF DEST="IMPLEMENTATION-DATA-TYPE">/DataType/Boolean</TYPE-TREF>
</FIELD>
</FIELDS>
</SERVICE-INTERFACE>
</ELEMENTS>
</AR-PACKAGE>
</AR-PACKAGES>
</AR-PACKAGE>
</AR-PACKAGES>
</AUTOSAR>
工具链生成框架代码
使用AUTOSAR AP工具链(如arxml2cpp或ara::com代码生成器)处理上述ARXML,生成以下核心文件:
example_service_interface.h— 服务接口类型定义(方法签名、事件、字段)example_service_skeleton.h/.cpp— 服务端骨架类SkeletonExampleServiceexample_service_proxy.h/.cpp— 客户端代理类ProxyExampleService
生成代码的关键结构如下(示意,实际由工具生成):
// example_service_skeleton.h(工具生成)
#include <ara/com/skeleton.h>
namespace demo { namespace soa {
class SkeletonExampleService : public ara::com::Skeleton {
public:
SkeletonExampleService(ara::core::InstanceSpecifier instance)
: ara::com::Skeleton(instance),
CounterEvent(*this, "CounterEvent"),
Status(*this, "Status") {}
// 方法:Add(服务端需实现)
virtual ara::core::Future<int32_t> Add(int32_t left, int32_t right) = 0;
// 方法:GetVersion(服务端需实现)
virtual ara::core::Future<ara::core::String> GetVersion() = 0;
// 事件发送器
ara::com::Event<uint32_t> CounterEvent;
// 字段
ara::com::Field<bool> Status;
};
}} // namespace demo::soa
服务端实现示例
// server.cpp(手写实现)
#include "example_service_skeleton.h"
#include <iostream>
using namespace demo::soa;
class ExampleServiceImpl : public SkeletonExampleService {
public:
explicit ExampleServiceImpl(ara::core::InstanceSpecifier instance)
: SkeletonExampleService(instance) {}
ara::core::Future<int32_t> Add(int32_t left, int32_t right) override {
ara::core::Promise<int32_t> promise;
promise.set_value(left + right);
return promise.get_future();
}
ara::core::Future<ara::core::String> GetVersion() override {
ara::core::Promise<ara::core::String> promise;
promise.set_value("1.0.0");
return promise.get_future();
}
};
int main() {
ara::core::InstanceSpecifier spec("demo/soa/ExampleService");
ExampleServiceImpl service(spec);
service.OfferService();
std::cout << "Service offered. Press Ctrl+C to exit." << std::endl;
while (true) {}
return 0;
}
客户端调用示例
// client.cpp(手写实现)
#include "example_service_proxy.h"
#include <iostream>
using namespace demo::soa;
int main() {
ara::core::InstanceSpecifier spec("demo/soa/ExampleService");
ProxyExampleService proxy(spec);
proxy.FindService();
// 调用Add方法
auto result = proxy.Add(3, 4).get();
std::cout << "Add(3,4) = " << result << std::endl;
// 调用GetVersion方法
auto version = proxy.GetVersion().get();
std::cout << "Version = " << version << std::endl;
return 0;
}
编译与运行验证
依赖:AUTOSAR AP R20-11兼容工具链、C++14编译器、ara::com运行时库。编译命令:
# 服务端
g++ -std=c++14 server.cpp example_service_skeleton.cpp -o server -lara_com
# 客户端
g++ -std=c++14 client.cpp example_service_proxy.cpp -o client -lara_com
运行验证:
- 终端1执行
./server,观察输出Service offered。 - 终端2执行
./client,观察输出:
预期输出:
Add(3,4) = 7
Version = 1.0.0
判定标准:客户端成功打印上述两行结果,且服务端无异常退出,即验证通过。若工具链生成代码接口与上述示意有差异,以工具链实际生成的头文件为准调整实现。