1. 创建第一个AUTOSAR AP服务

创建第一个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 — 服务端骨架类SkeletonExampleService
  • example_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. 终端1执行./server,观察输出Service offered。
  2. 终端2执行./client,观察输出:
预期输出:
Add(3,4) = 7
Version = 1.0.0

判定标准:客户端成功打印上述两行结果,且服务端无异常退出,即验证通过。若工具链生成代码接口与上述示意有差异,以工具链实际生成的头文件为准调整实现。

服务接口结构示意

ExampleService 接口结构 «interface» ExampleService Methods + Add(left:int32, right:int32):int32 + GetVersion():String Events + CounterEvent:uint32 Fields + Status:Boolean namespace: demo::soa 工具链生成物 SkeletonExampleService ProxyExampleService example_service_interface.h 服务端实现Skeleton,客户端使用Proxy,通过ara::com运行时通信