AUTOSAR_EXP_ARAComAPI的5章笔记(7)

5.3.6 Methods

对于远程服务提供的每种方法,Proxy Class都包含一个特定于该方法的包装类的成员。

在我们的示例中,有三种方法,相应的成员分别名为 Calibrate(类型为 methods::Calibrate)、Adjust(类型为 methods::Adjust)和 LogCurrentState(类型为 methods::LogCurrentState)。就像事件类一样,代理类所需的方法类是在一个特定的命名空间 methods 中生成的,而这个 methods 命名空间包含在代理命名空间内。代理中的方法成员用于调用我们的代理所连接的可能是远程服务实例所提供的方法。

让我们来看一下示例中生成的方法类 —— 在这里我们选取 Adjust 方法:

class Adjust {
public:
    /**
     * 对于所有的输出参数和非空返回参数
     * 会生成一个包含该非空返回值和/或输出参数的封闭结构体。
     */
    struct Output {
        bool success;
        Position effective_position;
    };

    /**
     * \brief 此操作将会调用该方法。
     *
     * 通过操作符,通信管理将会进行调用并返回一个 future(异步结果),它允许调用者获取方法的结果。
     *
     * \param[in] target_position  参考服务描述。
     *
     * \return 一个包含 Output 结构体的 future。
     */
    ara::core::Future<Output> operator()(const Position &target_position);
};

所以这个方法包装类并不是那么复杂。它仅仅由两部分组成:一个内部结构(struct Output)定义,它汇总了该方法所有的输出(OUT )/ 输入输出(INOUT )参数;还有一个括号运算符重载,使类看起来像函数,用于调用服务方法。

该运算符将服务方法的所有输入(IN )/ 输入输出(INOUT )参数作为输入(IN)参数包含在内。这意味着在抽象服务方法描述中的输入输出(INOUT )参数在 ara::com API 中被拆分成一对输入(IN)和输出(OUT)参数。

对一个服务方法(不是 “单向方法”)调用的返回值是一个ara::core::Future,其中模板参数是内部结构的类型,这个内部结构汇总了该方法的所有输出(OUT )参数。在下一小节中将详细介绍这个 ara::core::Future

5.3.6.1 One-Way aka Fire-and-Forget Methods

在介绍“普通” 方法提供的功能之前,我们在此简要介绍一下 “单向方法”,其实,我们在上一节中已经提到了这个术语。 ara::com 支持一种特殊的方法,我们称之为 “单向(one-way)” 或 “发射后不管(fire-and-forget)”。从技术上讲,这是一种只有输入(IN)参数的方法 —— 没有输出(OUT)参数,并且不允许引发错误。也无法与服务器进行握手 / 同步!因此,客户端 / 调用者完全无法得知服务器 / 被调用者是否已经处理了 “单向” 调用。

在某些通信模式中,这种尽力而为的方法就完全足够了。在这种情况下,从资源的角度来看,这种 “单向 / 发射后不管” 的语义是非常轻量级的。如果我们查看这种方法的签名,我们会发现它比常规方法的签名更简单。

class LogCurrentState {
public:
    /**
     * \brief 此操作将会调用该方法。
     *
     * 通过操作符,通信管理将会进行调用。
     *
     * 这是一个单向(one - way)方法,所以不会提供任何反馈(返回值/输出参数)。
     */
    void operator();
};
5.3.6.2 Event-Driven vs Polling access to method results

与上一节(5.3.5 小节)中描述的对事件数据的访问类似,我们也为基于事件驱动轮询的方法提供了 API 支持,以用于访问服务方法调用的结果。

这两种方法之间的区别的神奇之处在于返回的 ara::core::Futureara::core::Future 基本上是 C++11/C++14 std::future 类的扩展版本;详情见 [Specification of Adaptive Platform Core.pdf]

就像在事件数据访问中一样,这里的事件驱动意味着,一旦方法调用结果到达,方法的调用者(带有代理实例的应用程序)就会被 ara::com实现(Communication Management implementation)通知。

对于  ara::com实现来说,这意味着它必须在幕后设置某种等待机制(WaitEvent),一旦方法结果可用,该机制就会被唤醒,以通知 ara::com用户。那么 ara::core::Future 的不同使用模式是如何工作的呢?让我们更深入地了解一下我们的 ara::core::Future  及其提供的接口:

// 定义一个名为 future_status 的枚举类,基于无符号 8 位整数
enum class future_status : uint8_t
{
    ready,    // 表示共享状态已准备好
    timeout   // 表示在指定的超时时间过去之前,共享状态没有准备好
};

// 定义一个模板类 Future,它接受类型参数 T 和类型参数 E(默认为 ErrorCode)
template <typename T, typename E = ErrorCode>
class Future
{
public:
    // 默认构造函数,使用 noexcept 修饰表示不会抛出异常
    Future() noexcept = default;
    // 析构函数
    ~Future();

    // 禁用拷贝构造函数
    Future(const Future&) = delete;
    // 禁用拷贝赋值运算符
    Future& operator=(const Future&) = delete;

    // 移动构造函数,使用 noexcept 修饰表示不会抛出异常
    Future(Future&& other) noexcept;
    // 移动赋值运算符,使用 noexcept 修饰表示不会抛出异常
    Future& operator=(Future&& other) noexcept;

    /**
     * @brief 获取值
     *
     * 此函数的行为应与相应的 std::future 函数相同
     *
     * @returns 类型为 T 的值
     * @error 域:错误 通过 Promise::SetError 放入相应 Promise 中的错误
     *
     */
    T get();

    /**
     * @brief 获取结果
     *
     * 与 get()类似,此调用会阻塞直到值或错误可用。不过,此调用永远不会抛出异常
     *
     * @returns 包含值或错误的 Result
     * @error 域:错误 通过 Promise::SetError 放入相应 Promise 中的错误
     *
     */
    Result<T, E> GetResult() noexcept;

    /**
     * @brief 检查 Future 是否有效,即是否具有共享状态
     *
     * 此函数的行为应与相应的 std::future 函数相同
     *
     * @returns 如果 Future 可用则返回 true,否则返回 false
     */
    bool valid() const noexcept;

    /**
     * @brief 等待值或错误变为可用
     *
     * 此函数的行为应与相应的 std::future 函数相同
     */
    void wait() const;

    /**
     * @brief 等待给定的时间段,或者直到值或错误变为可用
     *
     * 此函数的行为应与相应的 std::future 函数相同
     *
     * @param timeoutDuration 要等待的最大持续时间
     * @returns 表示是超时还是值可用的状态
     */
    template <typename Rep, typename Period>
    future_status wait_for(const std::chrono::duration<Rep, Period>& timeoutDuration) const;

    /**
     * @brief 等待直到给定的时间,或者直到值或错误变为可用
     *
     * 此函数的行为应与相应的 std::future 函数相同
     *
     * @param deadline 要等待的最晚时间点
     * @returns 表示是否到达时间或值是否可用的状态
     */
    template <typename Clock, typename Duration>
    future_status wait_until(const std::chrono::time_point<Clock, Duration> deadline) const;

    /**
     * @brief 注册一个可调用对象,当 Future 准备好时调用该对象
     *
     * 当调用 @a func 时,保证 get()和 GetResult()不会阻塞
     *
     * @a func 可以在此调用的上下文中调用,也可以在 Promise::set_value()或 Promise::SetError()或其他地方的上下文中调用
     *
     * @a then 的返回类型取决于 @a func 的返回类型(也称为延续)
     *
     * 设 U 为延续的返回类型(即与 std::result_of_t<std::decay_t<F>(Future<T,E>)>等效的类型)
     * - 如果 U 对于某些类型 T2、E2 是 Future<T2,E2>,那么 @a then()的返回类型是 Future<T2,E2>。这称为隐式 Future 展开
     * - 如果 U 对于某些类型 T2、E2 是 Result<T2,E2>,那么 @a then()的返回类型是 Future<T2,E2>。这称为隐式 Result 展开
     * - 否则它是 Future<U,E>
     *
     * @param func 要注册的可调用对象
     * @returns 延续结果的新 Future 实例
     */
    template <typename F>
    auto then(F&& func) -> Future<SEE_COMMENT_ABOVE>;

    /**
     * @brief 返回异步操作是否已完成
     *
     * 如果此函数返回 true,则保证 get()、GetResult()和等待调用不会阻塞
     *
     * 如果 valid()返回 false,则此函数的行为未定义
     *
     * @returns 如果 Future 包含值或错误则返回 true,否则返回 false
     */
    bool is_ready() const;
};

ara::core::GetResult ()ara::core::Future 对象中返回结果(Result)或者错误(Error),并且不会抛出异常。get () 返回相应的 ara::core::Future  并且 / 或者抛出异常。

有关自适应平台中错误处理方法的详细文档,请参阅 [Specification of Adaptive Platform Core.pdf] 中 “错误处理” 章节。

下面是使用 “基于异常” 的方法来同步调用一个方法的示例:

using namespace ara::com;

int main() {
    // 一些获取句柄的代码
    //...
    RadarServiceProxy service(handle);
    // 通过服务的 Calibrate 方法(传入 myConfigString 参数)调用,得到一个包含 Calibrate::Output 类型的 Future 对象
    Future<Calibrate::Output> callFuture = service.Calibrate(myConfigString);

    /**
     * 现在我们进行一个阻塞式的 get()调用,当接收到结果(有效结果或者异常)时,该调用将会返回。
     *
     * 如果 Calibrate 方法可能抛出异常并且服务端已经设置了异常,那么这个异常将会通过 get()抛出
     */
    Calibrate::Output callOutput = callFuture.get();

    // 对得到的 callOutput 进行处理...
    return 0;
}

简而言之:从开发人员的角度来看,对服务方法的同步调用仅仅包含()操作符调用语法,以及随后对返回的 future (同步 / 异步结果)进行阻塞式的 get () 调用。除了从对 get () 的阻塞调用中恢复执行之外,一旦方法结果可用,用户还有其他方式从通信管理实现中获得通知:

  • wait” 的变体,ara::core::Future std::future 中继承了这些变体。它们主要提供了阻塞等待 future 完成的功能。

  • 通过 then()注册一个回调方法。这是对 std::future  的扩展之一;详见  [Specification of Adaptive Platform Core.pdf]

简单的无参数的 wait() 变体与 get () 具有相同的阻塞语义,即阻塞直到 future 有一个有效的结果(值或异常)。 “wait” 的变体,你要么给出一个持续时间( wait_for())要么给出一个目标时间点( wait_until()),如果  future 有一个有效的结果或者超时 / 最后期限限制已到,它们就会返回 —— 因此它们都返回 future_status 以区分这些情况。 获得  future 结果(有效或异常)通知的最后一种可能性是通过 then()注册一个回调方法。这是  ara::core::future std::future  的扩展之一。

如你所见,到目前为止我们讨论的(并且在示例中部分展示了)获取 future 方法结果的所有可能性 —— 阻塞式的 “get”、所有 “wait” 变体和 “then”—— 都是事件驱动的。也就是说,方法结果(或错误)的到达事件要么导致被阻塞的用户线程恢复执行,要么导致对用户提供的函数的调用!

当然,有些情况下,ara::com用户根本不希望他的应用程序(进程)被某些方法调用返回事件激活!想象一个典型的实时(RT)应用程序,它必须完全控制自己的执行。我们已经在事件数据访问的上下文中讨论了这个实时 / 轮询用例(小节 5.3.5.3)。对于方法调用,同样的方法也适用!

因此,我们预见到了与  ara::core::future 相关的以下使用模式:通过()操作符调用服务方法后,只需使用 ara::core::Future::is_ready () 进行轮询,以查看方法调用是否已经完成。此调用被定义为非阻塞的。当然,它可能涉及一些系统调用 / 上下文切换(例如查看一些内核缓冲区),这并不是无代价的,但它不会阻塞!在ara::core::Future::is_ready () 返回 true 之后,可以保证下一次对 ara::core::Future::get () 的调用不会阻塞,而是在没有错误的情况下立即返回有效的值,或者在出现错误的情况下抛出异常。

5.3.6.3 Canceling Method Result

在某些情况下,你可能已经通过()操作符调用了一个服务方法,该方法返回了一个  ara::core::future ,但你已经不再关心结果了。

甚至可能你已经通过 ara::core::Future::then() 为它注册了一个回调。与其放任不管并 “忽略” 这个回调,你应该明确地告知通信管理(Communication Management)。

这样可以释放资源,并避免在绑定实现层面产生不必要的处理负载。要告知你不再对方法调用结果感兴趣,只需让  ara::core::Future  超出作用域,这样它的析构函数(destructor)就会被调用。

调用  ara::core::Future  的析构函数是向绑定实现发出的一个信号,表示不应再调用为此  future 注册的任何回调,方法调用结果的预留 / 分配内存可以被释放,并且方法结果的事件等待机制应该停止。

显然,为了触发对析构函数的调用,你可以让  future 超出作用域。根据应用程序架构的不同,这可能并不可行,因为你可能已经将返回的  ara::core::Future  分配给了某个作用域更大的变量。

为了解决这个问题, ara::core::Future 是可默认构造的。因此,你可以像下面的示例所示,简单地用一个默认构造的实例覆盖变量中返回的  ara::core::Future 

using namespace ara::com;

// 定义一个存储 Calibrate::Output 类型的 Future 对象
Future<Calibrate::Output> calibrateFuture;

int main() {
    // 一些获取句柄的代码
    //...
    RadarServiceProxy service(handle);
    // 调用服务的 Calibrate 方法(传入 myConfigString 参数),并将返回的 Future 对象赋值给 calibrateFuture
    calibrateFuture = service.Calibrate(myConfigString);

    /**
     * 发生了一些状态改变,使得 calibrate 方法的结果变得多余了...
     * 
     * 我们通过将变量重置为一个新的默认构造的 Future 对象来强制删除(原来的 Future 对象)
     */
    calibrateFuture = Future<Calibrate::Output>();

    // 继续执行其他操作...
    return 0;
}

### 回答1: autosar_exp_vfb.pdf是一个与AUTOSARAutomotive Open System Architecture)相关的文件。该文件中的“exp”代表“实验”(experiment),“vfb”代表“虚拟功能总成”(virtual functional bus)。 AUTOSAR是一种开放的、标准化的汽车电子系统架构,旨在提供一种通用的软件架构和平台,使汽车制造商和供应商能够更轻松地开发可重用和可互换的汽车电子控制单元(ECU)。AUTOSAR定义了一组标准、协议和工具链,用于汽车电子系统中的软件和硬件组件之间的通信与互操作。 在autosar_exp_vfb.pdf文件中,主要介绍了AUTOSAR架构中的虚拟功能总成(VFB)的实验研究内容。虚拟功能总成是AUTOSAR架构中的重要概念之一,它是一种通过软件模型和封装技术来实现的虚拟函数,用于实现不同的汽车功能。通过VFB,不同的软件模块可以以相对独立的方式进行开发和测试,并在已经定义好的接口上进行互操作。 autosar_exp_vfb.pdf文件可能包括以下内容: 1. 虚拟功能总成的设计原理和方法:介绍了VFB的设计原则和实现方法,包括软件模型的构建、接口的定义、封装技术的应用等。 2. VFB与AUTOSAR架构的关系:解释了VFB在AUTOSAR架构中的位置和作用,以及VFB与其他AUTOSAR模块(如ECU软件组件等)之间的协作关系。 3. VFB的实验研究案例:给出了一些使用VFB实现特定汽车功能的实验案例,例如车身控制、驾驶辅助系统、车载娱乐等。 4. VFB的优势和挑战:分析了使用VFB进行软件开发的优势和挑战,如适应不同需求、提高开发效率、确保系统可靠性等。 总而言之,autosar_exp_vfb.pdf文件提供了关于AUTOSAR架构中虚拟功能总成的实验研究内容,介绍了其设计原理、与AUTOSAR架构的关系、实验案例以及优势和挑战。 ### 回答2: autosar_exp_vfb.pdf 是一个关于AUTOSARAUTomotive Open System ARchitecture)的实验报告文件。 AUTOSAR是一个汽车领域的开放系统架构标准,旨在促进汽车电子控制单元(ECU)软件的开发、集成和共享。该标准由一些汽车制造商、电子供应商和软件供应商共同组成的联盟开发,旨在提高汽车电子系统的可靠性、可扩展性和安全性。 autosar_exp_vfb.pdf 这个实验报告文件探讨了AUTOSAR架构中的虚拟功能总线(VFB)。虚拟功能总线是AUTOSAR的一个重要概念,用于在ECU之间进行通信和数据交换。 实验报告详细介绍了VFB的原理和实现方法,包括通信协议、消息传递方式和数据处理过程。它还讨论了VFB的优点和应用场景,并提供了一些实际案例和实验结果。 通过阅读autosar_exp_vfb.pdf,读者可以了解到VFB在AUTOSAR架构中的重要性和作用,以及如何使用VFB来实现ECU之间的通信和数据交换。这对汽车电子系统的开发人员和工程师来说是非常有价值的信息,可以帮助他们更好地理解和应用AUTOSAR标准。同时,这个实验报告也为研究AUTOSAR和汽车电子系统的学者和研究人员提供了一个有用的参考和指导。 ### 回答3: autosar_exp_vfb.pdf是一个自动驾驶相关的文件。该文件是Autosar Exp软件的一部分,主要涵盖了Virtual Function Bus(VFB)的概念和应用。 Virtual Function Bus是一个在自动驾驶系统中使用的通信框架,旨在实现模块化开发和集成。它允许系统中的不同功能模块以一种标准化的方式进行通信和互操作。 autosar_exp_vfb.pdf文件提供了关于VFB的详细说明和使用指南。在这个文件中,我们可以找到关于VFB的架构、功能和特性的详细描述。它还介绍了VFB的设计原则和使用方法,以及与其他Autosar软件模块的集成方式。 此外,autosar_exp_vfb.pdf文件还提供了一些示例应用和用例,以帮助开发人员理解和应用VFB。这些示例涵盖了VFB在自动驾驶系统中的实际应用,包括传感器数据的处理、决策制定和控制执行等方面。 总而言之,autosar_exp_vfb.pdf是一个重要的文件,它为开发人员提供了关于Virtual Function Bus的全面理解,帮助他们在自动驾驶系统中有效地设计和集成功能模块。这个文件对于开发自动驾驶系统的工程师和研究人员来说是一个有价值的参考资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青草地溪水旁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值