3. 基于Manifest的应用配置
任务说明
本案例在AUTOSAR Adaptive Platform(AP)框架下,基于ara::com通信中间件,实现两个进程间的服务发现与事件订阅/发布。目标是通过标准C++代码,完成一个可编译、可运行的最小闭环:服务端(Provider)注册一个事件(Event),客户端(Consumer)发现该服务并订阅事件,服务端周期性发布事件数据,客户端接收并校验数据完整性。
实现方案
采用AUTOSAR AP的ara::com标准接口,使用SomeIP作为底层传输协议(由ara::com实现封装)。服务端通过ara::com::ServiceProvider注册服务,定义事件CounterEvent(数据类型为uint32计数器);客户端通过ara::com::ServiceProxy发现服务并订阅事件。为保持案例独立可复现,使用ara::com的仿真实现(如AraComSim或基于vSomeIP的轻量实现),并提供CMake构建脚本。
代码实现
// service_interface.h - 服务接口定义
#pragma once
#include <ara/com/ServiceProvider.h>
#include <ara/com/ServiceProxy.h>
#include <ara/com/Event.h>
#include <cstdint>
// 服务ID与事件ID(需在服务清单中注册)
constexpr ara::core::ServiceId kServiceId = 0x1234;
constexpr ara::core::EventId kCounterEventId = 0x0001;
// 事件数据类型
struct CounterEventData {
uint32_t counter;
};
// 服务接口(Provider侧)
class CounterServiceProvider : public ara::com::ServiceProvider {
public:
CounterServiceProvider() : ara::com::ServiceProvider(kServiceId) {
// 注册事件
counterEvent = CreateEvent<CounterEventData>(kCounterEventId);
}
ara::com::Event<CounterEventData> counterEvent;
};
// 服务接口(Proxy侧)
class CounterServiceProxy : public ara::com::ServiceProxy {
public:
CounterServiceProxy() : ara::com::ServiceProxy(kServiceId) {
// 创建事件订阅句柄
counterEvent = CreateEvent<CounterEventData>(kCounterEventId);
}
ara::com::Event<CounterEventData> counterEvent;
};
// provider_main.cpp - 服务端进程
#include "service_interface.h"
#include <ara/com/ServiceProvider.h>
#include <ara/com/Event.h>
#include <ara/com/ServiceRegistry.h>
#include <thread>
#include <chrono>
#include <iostream>
int main() {
// 初始化通信运行时
ara::com::Runtime::Initialize();
// 注册服务
CounterServiceProvider provider;
ara::com::ServiceRegistry::Instance().RegisterService(provider);
std::cout << "[Provider] Service registered, ID=0x" << std::hex << kServiceId << std::endl;
// 周期性发布事件
uint32_t counter = 0;
while (true) {
CounterEventData data{counter++};
provider.counterEvent.Send(data);
std::cout << "[Provider] Sent counter=" << data.counter << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
// consumer_main.cpp - 客户端进程
#include "service_interface.h"
#include <ara/com/ServiceProxy.h>
#include <ara/com/ServiceRegistry.h>
#include <ara/com/Event.h>
#include <ara/com/Runtime.h>
#include <functional>
#include <iostream>
#include <thread>
#include <chrono>
int main() {
ara::com::Runtime::Initialize();
// 查找服务(阻塞等待服务可用)
auto& registry = ara::com::ServiceRegistry::Instance();
auto handle = registry.FindService(kServiceId);
if (!handle) {
std::cerr << "[Consumer] Service not found" << std::endl;
return -1;
}
// 创建代理并订阅事件
CounterServiceProxy proxy;
proxy.counterEvent.SetReceiveHandler([](const CounterEventData& data) {
std::cout << "[Consumer] Received counter=" << data.counter << std::endl;
});
proxy.counterEvent.Subscribe();
std::cout << "[Consumer] Subscribed to event, waiting..." << std::endl;
// 运行10秒后退出(演示用)
std::this_thread::sleep_for(std::chrono::seconds(10));
proxy.counterEvent.Unsubscribe();
return 0;
}
# CMakeLists.txt - 构建脚本
cmake_minimum_required(VERSION 3.10)
project(ara_com_event_demo)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 假设ara::com仿真库已安装(如AraComSim)
find_package(ara_com REQUIRED)
add_executable(provider provider_main.cpp)
target_link_libraries(provider ara::com)
add_executable(consumer consumer_main.cpp)
target_link_libraries(consumer ara::com)
运行与验证
依赖说明:需要ara::com的仿真实现(如AraComSim或vSomeIP封装库),并提供CMake包配置文件。若使用真实AUTOSAR AP栈,需替换为对应的RTE配置。
构建与运行:
mkdir build && cd build
cmake ..
make
# 终端1:启动服务端
./provider
# 终端2:启动客户端
./consumer
验证方法:观察两个终端输出。服务端每秒打印[Provider] Sent counter=N(N从0递增);客户端应同步打印[Consumer] Received counter=N,且N的序列与服务端一致(允许因调度延迟出现少量丢包,但接收到的值必须严格递增且无乱序)。运行10秒后客户端自动退出,服务端继续运行(可用Ctrl+C终止)。
判定标准:若客户端接收到的counter值序列与服务端发送的序列一致(无跳变、无重复、无乱序),且进程间通信无崩溃,则判定案例通过。