验证您的 VSIDL 目录是否包含必要的 build、protobuf 和 VSIDL 文件。如需从现有示例开始,您可以在
/system/software_defined_vehicle/samples/vsidl/stable/catalog下找到有效目录文件夹的示例。示例目录结构:
my_catalog/ ├── Android.bp # Defines rust_protobuf modules for .proto files ├── types.proto # Protobuf message / RPC service definitions └── architecture.vsidl # VSIDL service bundle definitions编写自定义代码以实现业务逻辑。
vsidlc会为 Rust 生成中间件绑定和服务软件包框架(lib.rs、service_bundle.rs和main.rs)。如果您使用 C++ 编写服务包,请直接实现生命周期 (libsdv_lifecycle_client_cpp) 和通信 (libsdv_comms_cpp) 接口:- RPC 服务器 (Rust):实现
lib.rs中生成的特征。 - 发布、订阅和 RPC 客户端 (Rust):在
service_bundle.rs中调用生成的函数,以便与其他服务进行交互。 生命周期和通信 (C++):子类化
ServiceBundle,并在onStart中初始化发布者、订阅者或 RPC 端点。
Rust
通过运行以下命令生成框架实现:
vsidlc -c /path/to/catalog -o /path/to/output --services使用
--services标志运行vsidlc会为每个服务包生成一个样板 Rust 实现。这会提供源代码 (main.rs) 和包含所有依赖项的 build 配置文件 (Android.bp),以便您的软件包可以立即交换默认消息,而您可以专注于业务逻辑。对于每个服务包,请在以下位置找到 Rust 实现:
/path/to/output/services/ServiceBundleName/src/main.rs。默认情况下,生成的实现会创建具有默认值的消息,并在发布方和订阅方或 RPC 客户端和服务器之间发送这些消息。如需修改此行为,请在
main.rs中找到TODO注释,并根据您的偏好进行调整。例如:rust async fn handle_tire_pressure_range_unique_publisher( publisher: sdv::mw::Publisher<TirePressureRange>, ) { loop { // TODO: Modify the frequency of publishing messages here. sleep(Duration::from_secs(1)).await; // TODO: Modify the message content here. let message = TirePressureRange::default(); info!("Publishing on TirePressureRange#UNIQUE"); publisher.publish(&message).unwrap(); } }为确保下次运行
vsidlc时不会覆盖您对生成的文件所做的修改,请将services文件夹移出/path/to/output文件夹。
C++
创建一个新的头文件
src/lib.hpp,其中包含服务包的类:#pragma once #include <sdv/service_bundle.h> #include <sdv/context.hpp> namespace com::sdv::oem::service_bundle { // Sample implementation of the service bundle interface. class ServiceBundleName : public android::sdv::service_bundle::ServiceBundle { public: ServiceBundleName(sdv_comms::ctx::Context context); ~ServiceBundleName(); void onStart() override; void onStop() override; }; } // namespace com::sdv::oem::service_bundle创建一个新的源文件
src/lib.cpp,其中包含类实现:#include "src/lib.hpp" #include <sdv/sb_macro.h> #include <iostream> using com::sdv::oem::service_bundle::ServiceBundleName; // Register the new service bundle. REGISTER_SERVICE_BUNDLE(ServiceBundleName); // Sample implementation of the service bundle interface. namespace com::sdv::oem::service_bundle { // Creates a new instance of the ServiceBundleName. // Called when service bundle is created by the system. // Context object is provided as a parameter that gives access to the // communication stack APIs. ServiceBundleName::ServiceBundleName([[maybe_unused]] sdv_comms::ctx::Context context) : ServiceBundle(context) { // Memory allocations and static data loading should be done as // part of this method. // // Loading of the dynamic resources (sockets, files, etc) // is strongly discouraged due to possible Suspend-to-RAM scenario. // // The dynamic data can be loaded in the onStart method. } // Called when the service bundle is started by the system. void ServiceBundleName::onStart() { // Allocate dynamic resources (sockets, files, publishers, and // subscribers such as TirePressureRange#UNIQUE) during this call. } // Called when the service bundle is stopped by the system in preparation // for shutdown or suspend to RAM/Disc. void ServiceBundleName::onStop() { // Stop active publishing loops and release the dynamic resources // that were allocated in the onStart method. } // Called when the service bundle is destroyed by the system. ServiceBundleName::~ServiceBundleName() { // Static resources deallocation needs to be implemented in the destructor. } } // namespace com::sdv::oem::service_bundle在新的或现有的
Android.bp文件中创建服务软件包库 Soong 目标:// Service bundle library. cc_library_shared { name: "libservice_bundle", srcs: ["src/lib.cpp",], // Allows the library to be available inside APEX. apex_available: [ "//apex_available:platform", "//apex_available:anyapex", ], shared_libs: [ // Service Bundle lifecycle C++ API. "libsdv_lifecycle_client_cpp", // commstack library that provides context object reference "libsdv_comms_cpp", ], // Service bundle package is packed into /product apexes. product_specific: true, }
- RPC 服务器 (Rust):实现
后续步骤
如需部署服务包,请参阅构建和部署服务包。