Autosar 软件组件

Autosar Software Component

我已经阅读了几份 AUTOSAR 文档。现在,我只关心开发软件组件。我有两个软件组件设计,请看下图。

解释:

  1. 我从端口 1 和端口 2 得到数据。当有新数据到来时,每个端口将对应 RunnableEntity 和 运行。然后,RunnableEntity 将该数据设置为 InterRunnableVariable。主 RunnableEntityRunnableEntity 1‖ 将处理 InterRunnableVariable 以生成输出。
  2. 数据自由进入端口,在缓冲区等待处理。然后,唯一的RunnableEntity将借助公共全局变量的一些帮助来处理数据(全局变量的用途与InterRunnableVariable相同)。

我的问题是,

  1. 设计 1 和 2 可行吗?
  2. 如果设计1和2是真的,从时间流程、实施时间等方面来看,你更喜欢哪一个?
  3. 密码对吗?如何处理事件和InterRunnableVariable?

感谢您的帮助。

====================注释后添加代码===================== ===

设计 1

/* Runnable Entity 1*/
/* Event : TimeEvent 25ms */
void re1(void){
    data_output out;
    irv irv1 = Rte_IrvIread_re1_irv1(); 
    irv irv2 = Rte_IrvIread_re1_irv2();
    irv irv3 = Rte_IrvIread_re1_irv3();

    out = DataProcess(&irv1,&irv2,&irv3);

    Rte_Write_re1_port3_out();
}

/* Runnable Entity 2*/
/* Event : DataReceiveErrorEvent on port1 */
void re2(void){     
    irv irv2 = Rte_IrvIread_re1_irv2();

    modify(&irv2);

    Rte_IrvIwrite_re1_irv2(irv2);
}

/* Runnable Entity 3*/
/* Event : DataReceiveEvent on port1 */
void re2(void){
    data_input1 in;
    Std_RetrunType status;

    irv irv1 = Rte_IrvIread_re1_irv1(); 
    status = Rte_Receive_re1_port1_input(&in);
    if (status == RTE_E_OK) {
        modify(&irv1,in);
        Rte_IrvIwrite_re1_irv1(irv1);
    }
}

/* Runnable Entity 4*/
/* Event : DataReceiveEvent on port2 */
void re2(void){
    data_input2 in;
    Std_RetrunType status;

    irv irv3 = Rte_IrvIread_re1_irv3(); 
    status = Rte_Receive_re1_port2_input2(&in);
    if (status == RTE_E_OK) {
        modify(&irv3,in2);
        Rte_IrvIwrite_re1_irv3(irv3);
    }
}

设计 2

/*Global Variable*/
global_variable1 gvar1; /* Equal with InterVariable 1 in Design 1*/
global_variable2 gvar2; /* Equal with InterVariable 2 in Design 1*/
global_variable3 gvar3; /* Equal with InterVariable 3 in Design 1*/

/* Runnable Entity 1*/
/* Event : TimeEvent 25ms */
void re1(void){
    data_output out;
    GetData1()
    GetData2()


    out = GetOutputWithGlobalVariable();

    Rte_Write_re1_port3_out(out);
}

/* Get Data 1*/
void getData1(){    
    Std_ReturnType status; /* uint8  */
    data_input1 in;

    do {
        status = Rte_Receive_re1_port1_input1(&in);
        if (status == RTE_E_OK) {
            modifyGlobalVariable(in);
        }
    } while (status != RTE_E_NO_DATA && status != RTE_E_LOST_DATA);

    if(status != RTE_E_LOST_DATA){
        modifyGlobalVariableWhenError();
    }
    return;
}

/* Get Data 2*/
void getData2(){    
    Std_ReturnType status; /* uint8  */
    data_input2 in;

    do {
        status = Rte_Receive_re1_port2_input2(&in);
        if (_status == RTE_E_OK) {
            modifyGlobalVariable2(in);
        }
    } while (status != RTE_E_NO_DATA && status != RTE_E_LOST_DATA);

    return;
}

我认为这两种解决方案都是可行的。主要区别在于,在第一个解决方案中,生成的 Rte 将管理全局缓冲区,而在第二个设计中,您必须自己处理缓冲区。 特别是如果您有多个可运行对象访问同一个缓冲区,'Rte' 将生成中断锁以保护数据一致性,或者如果“RunnableEntities”中的任务上下文 运行 不能,它将优化锁互相打扰。

即使您只有一个“RunnableEntity”,如第二个设计所示,“TimingEvent”也可能激活“RunnableEntity”和 DataReceivedEvent(虽然我不明白为什么你在第二个设计中遗漏了 DataReceivedEvent)。在这种情况下,'RunnableEntity' 是 运行 在访问相同数据的两个不同上下文中。

简而言之:我的建议是使用可运行变量并让 Rte 处理数据一致性、初始化等。 创建软件组件描述可能需要更多的努力,但是您只需使用生成的 IrvRead/IrvWrite 函数就可以了。

实际上我更喜欢第一个。

第二个有点取决于您的 SWC 描述,因为有端口数据访问的规范。根据这个定义,它取决于 RTE 是创建阻塞还是非阻塞 Rte_Receive.

[SWS_Rte_01288] 如果 dataReceivePointByArgument 中的 VariableAccess 应生成非阻塞 Rte_Receive API角色引用具有“事件”语义的必需 VariableDataPrototype。 (SRS_Rte_00051)

[SWS_Rte_07638] 如果具有“事件”语义的 VariableDataPrototype 被 dataReceivePointByValue 角色中的 VariableAccess 引用,RTE 生成器将拒绝配置. (SRS_Rte_00018)

[SWS_Rte_01290] 如果 dataReceivePointByArgument 角色引用中的变量访问,则应生成阻塞 Rte_Receive API一个必需的具有“事件”语义的 VariableDataPrototype,它又被 DataReceivedEvent 引用,而 DataReceivedEvent 被 WaitPoint 引用。 (SRS_Rte_00051)

另一方面,我不确定您的阻塞 Rte_Receive 与基于 TimingEvent 的 RunnableEntity 调用相比会发生什么。

还要考虑以下几点:

RTE_E_LOST_DATA 实际上意味着,由于传入数据溢出队列,您丢失了数据(Rte_Receive 仅适用于 swImplPoliy = queued,否则如果 swImplPolicy ! =排队你得到Rte_Read)。这不是明确的 Std_ReturnType 值,而是添加到 return 值的标志 -> OverlayedError)

RTE_E_TIMEOUT 将用于阻止 Rte_Receive

RTE_E_NO_DATA 将用于非阻塞 Rte_Receive

然后您应该检查为:

Std_ReturnType status;
status = Rte_Receive_..(<instance>, <parameters>);
if (Rte_HasOverlayedError(status)) {
    // Handle e.g. RTE_E_LOST_DATA
}
// not with Rte_Receive - if(Rte_IsInfrastructureError(status)) { }
else { /* handle application error with error code status */
    status = Rte_ApplicationError(status);
}