Autosar ClientServer/ SenderReceiver实践

0. 前言

在实际工程运用中,存在很多时序上的需求,也有类似于linux的信号机制。

所以这里说一下autosar下的下面两种机制使用方式

  • sender/receiver 来触发任务

  • event 触发任务

任务部署有以下三种情况

  • 任务内通信发生在同一任务执行的组件之间(因此是序列化的)

  • 任务间通信发生在同一个ECU中理论上并发的任务之间(实际上是需要看被激活的任务的调度方式)

  • ecu之间的通信发生在位于物理上不同的ecu上的并发执行组件之间

1. 需求

  • 两个swc

    • 作为server端,执行client的调用

    • 实现任务

    • 作为client,调用server

    • 写数据,触发任务

    • OperEvent_Input_SWC

    • OperEvent_SWC

2. 设计

2.1 OperEvent_Input_SWC

Component Port PortType Interface Client Server  Operation DataElement/Trigger Datatype
OperEvent_Input_SWC PP_Interface_Event1 P Port SR_Interface_Event1
Event1 uint8
OperEvent_Input_SWC PP_Interface_Event2 P Port SR_Interface_Event2
Event2 uint8
OperEvent_Input_SWC PP_Interface_Event3 R Port SR_Interface_Event3









OperEvent_Input_SWC PP_Interface_Event4 R Port SR_Interface_Event4









OperEvent_Input_SWC RPortPrototype_0 R Port CS_Interface_Oper RequestOpt0 Opt0_Req EventOptType
OperEvent_Input_SWC RPortPrototype_0 R Port CS_Interface_Oper RequestOpt1 Opt1_Req EventOptType

2.1.1 开发过程

Autosar ClientServer/ SenderReceiver实践

2.2 OperEvent_SWC

Component Port PortType Interface Client Server  Operation DataElement/Trigger Datatype
OperEvent_SWC RP_Interface_Event1 R Port SR_Interface_Event1
Event1 uint8
OperEvent_SWC RP_Interface_Event2 R Port SR_Interface_Event2
Event2 uint8
OperEvent_SWC PP_Interface_Event3 P Port SR_Interface_Event3









OperEvent_SWC PP_Interface_Event4 P Port SR_Interface_Event4









OperEvent_SWC PP_CS_Interface_Oper P Port CS_Interface_Oper RequestOpt0 Opt0_Req EventOptType
OperEvent_SWC PP_CS_Interface_Oper P Port CS_Interface_Oper RequestOpt1 Opt1_Req EventOptType

2.2.1 开发过程

Autosar ClientServer/ SenderReceiver实践

2.3 composition 图

Autosar ClientServer/ SenderReceiver实践

2.4 设计总结

2.4.1  任务间 client – server – 设计

2.4.1.1 OperEvent_Input_SWC 调用server。 Opt0 , Opt1

Autosar ClientServer/ SenderReceiver实践

2.4.1.2 OperEvent_SWC 作为server端,来执行Req0 Req1

Autosar ClientServer/ SenderReceiver实践

2.4.2 任务间 sender – receiver – 设计

2.4.2.1 OperEvent_Input_SWC 发送两个数据。 Event1, Event2

Autosar ClientServer/ SenderReceiver实践

2.4.2.2 OperEvent_SWC 作为执行端,设置两个sender receiver event 来获取(得知) 数据的到来

Autosar ClientServer/ SenderReceiver实践

3. 实现

3.1 OperEvent_Input_SWC  

3.1.1 runnable

3.1.1.1 OperEvent_Input_SWC_func

根据需求设计,component中只有一个runnable. 从下面的 Server Call Point 和  Data Write 能发现,我们来调用两个server 的服务,和写两个数据。

FUNC (void, OperEvent_Input_SWC_CODE) OperEvent_Input_SWC_func/* return value & FctID */
(
void
)
{

EventOptType Opt0_Req1;
Std_ReturnType asyncCall1;
EventOptType Opt1_Req2;
Std_ReturnType asyncCall2;
uint8 write3;
Std_ReturnType retWrite3;
uint8 write4;
Std_ReturnType retWrite4;

/* Local Data Declaration */

/*PROTECTED REGION ID(UserVariables :OperEvent_Input_SWC_func) ENABLED START */
/* Start of user variable defintions - Do not remove this comment */
/* End of user variable defintions - Do not remove this comment */
/*PROTECTED REGION END */
Std_ReturnType retValue = RTE_E_OK;
/* -------------------------------------- Data Read ----------------------------------------- */

/* -------------------------------------- Server Call Point -------------------------------- */

asyncCall1 = Rte_Call_RPortPrototype_0_RequestOpt0(Opt0_Req1);

asyncCall2 = Rte_Call_RPortPrototype_0_RequestOpt1(Opt1_Req2);

/* -------------------------------------- CDATA --------------------------------------------- */

/* -------------------------------------- Data Write ---------------------------------------- */
retWrite3 = Rte_Write_PP_Interface_Event1_Event1(write3);
retWrite4 = Rte_Write_PP_Interface_Event2_Event2(write4);

/* -------------------------------------- Trigger Interface --------------------------------- */

/* -------------------------------------- Mode Management ----------------------------------- */

/* -------------------------------------- Port Handling ------------------------------------- */

/* -------------------------------------- Exclusive Area ------------------------------------ */

/* -------------------------------------- Multiple Instantiation ---------------------------- */

/*PROTECTED REGION ID(User Logic :OperEvent_Input_SWC_func) ENABLED START */
/* Start of user code - Do not remove this comment */
/* End of user code - Do not remove this comment */
/*PROTECTED REGION END */

}

3.1.2 client server interface

3.1.2.1 Rte_Call_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0

client 调用一个server 具体的流程如下(autosar 文档截图)

Autosar ClientServer/ SenderReceiver实践

从下面代码也可以看出来,client端对Queue 进行了写入操作。也就是上图的 第一句Rte_Call()。

FUNC(Std_ReturnType, RTE_CODE)
Rte_Call_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0(VAR(EventOptType, AUTOMATIC) Opt0_Req) /* 2 */
{
  VAR(Std_ReturnType, AUTOMATIC) rtn = RTE_E_OK;
  Rte_CPT_OperEvent_SWC_PP_CS_Interface_Oper_RequestOpt0_QEType srvQEl;

  /* Box: Copy Opt0_Req to Rte_Ms_000004 begin */
  Rte_Ms_000004 = Opt0_Req;
  /* Box: Copy Opt0_Req to Rte_Ms_000004 end */

  if ( FALSE == Rte_Var_CPT_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0_outstanding )
  {
     srvQEl.Opt0_Req = Opt0_Req;
     srvQEl.clientQueue = &Rte_Queue_CPT_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0.cmn;
     Rte_Var_CPT_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0_outstanding = TRUE;
     rtn = Rte_WriteQueue(&Rte_Queue_CPT_OperEvent_SWC_PP_CS_Interface_Oper_RequestOpt0.cmn, &srvQEl);
     if ( ((VAR(StatusType, AUTOMATIC))E_OK) != rtn )
    {
        Rte_Var_CPT_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0_outstanding = FALSE;
    }

  }
  else
  {
     rtn = RTE_E_LIMIT;
  }
  return rtn;
}

3.1.3 sender receiver interface

3.1.3.1 Rte_Write_OperEvent_Input_SWC_PP_Interface_Event1_Event1

数据发送端调用写接口,对数据进行写入。

Autosar ClientServer/ SenderReceiver实践

从下面代码也可以看出来,数据写入的同时调用了 activateTask 来激活一个task. 随后这个task 就会交付给os 来调度使用。也做到了 同步的效果。

FUNC(Std_ReturnType, RTE_CODE)
Rte_Write_OperEvent_Input_SWC_PP_Interface_Event1_Event1(VAR(uint8, AUTOMATIC) data) /* 2 */
{
  VAR(Std_ReturnType, AUTOMATIC) rtn = RTE_E_OK;
  Std_ReturnType tmp;

  rtn = ((VAR(Std_ReturnType, AUTOMATIC))RTE_E_OK);
  /* Box: Send Event1 to /ETAS_FlatView/SwComponentTypes/ETAS_FlatView/CPT_OperEvent_SWC.RP_Interface_Event1 begin */
  /* Optimizer: Removed resource lock for assignment of parameter to global in highest pri task */
  Rte_Rx_000084 = data;
  Rte_ActCount_CPT_OperEvent_SWC_DataReceivedEvent_1 = TRUE;
  tmp = ActivateTask(OsTask_SysCore_EventTask);
  if ( ( ((VAR(StatusType, AUTOMATIC))E_OK) != tmp ) && ( ((VAR(Std_ReturnType, AUTOMATIC))E_OS_LIMIT) != tmp ) )
  {
     rtn = ((VAR(Std_ReturnType, AUTOMATIC))RTE_E_COM_STOPPED);
  }


  /* Box: Send Event1 to /ETAS_FlatView/SwComponentTypes/ETAS_FlatView/CPT_OperEvent_SWC.RP_Interface_Event1 end */
  /* Send complete */
  return rtn;
}

3.2 OperEvent_SWC

3.2.1 runnable

3.2.1.1 RE_OperaEvent1_func

暂时没有实现任何逻辑,但是从代码里可以看出来,这里调用了read 接口。

FUNC (void, OperEvent_SWC_CODE) RE_OperaEvent1_func/* return value & FctID */
(
void
)
{

uint8 iRead1;

/* Local Data Declaration */

/*PROTECTED REGION ID(UserVariables :RE_OperaEvent1_func) ENABLED START */
/* Start of user variable defintions - Do not remove this comment */
/* End of user variable defintions - Do not remove this comment */
/*PROTECTED REGION END */
Std_ReturnType retValue = RTE_E_OK;
/* -------------------------------------- Data Read ----------------------------------------- */
iRead1 = Rte_IRead_RE_OperaEvent1_RP_Interface_Event1_Event1();

/* -------------------------------------- Server Call Point -------------------------------- */

/* -------------------------------------- CDATA --------------------------------------------- */

/* -------------------------------------- Data Write ---------------------------------------- */

/* -------------------------------------- Trigger Interface --------------------------------- */

/* -------------------------------------- Mode Management ----------------------------------- */

/* -------------------------------------- Port Handling ------------------------------------- */

/* -------------------------------------- Exclusive Area ------------------------------------ */

/* -------------------------------------- Multiple Instantiation ---------------------------- */

/*PROTECTED REGION ID(User Logic :RE_OperaEvent1_func) ENABLED START */
/* Start of user code - Do not remove this comment */
/* End of user code - Do not remove this comment */
/*PROTECTED REGION END */

}

我们在设计的时候,这个runnable 什么时候运行的呢? 需求是收到一个data的 时候运行该runnable.

我们在前一个swc 里面进行了写data. 配置完成后,在rte里的代码判断了数据:

   /* Box: CPT_OperEvent_SWC end */
  /* Box: CPT_OperEvent_SWC begin */
  if ( Rte_ActCount_CPT_OperEvent_SWC_DataReceivedEvent_1 != FALSE )
  {
     Rte_ActCount_CPT_OperEvent_SWC_DataReceivedEvent_1 = FALSE;
     RE_OperaEvent1_func();
  }

Rte_ActCount_CPT_OperEvent_SWC_DataReceivedEvent_1这个event (数) 前面有进行赋值。

3.2.1.2 RE_OperaEvent2_func

同上

3.2.1.3 RE_OperaReq0_func
FUNC (void , OperEvent_SWC_CODE) RE_OperaReq0_func/* return value & FctID */
(
VAR(EventOptType, AUTOMATIC) Opt0_Req
)
{

/* Local Data Declaration */

/*PROTECTED REGION ID(UserVariables :RE_OperaReq0_func) ENABLED START */
/* Start of user variable defintions - Do not remove this comment */
/* End of user variable defintions - Do not remove this comment */
/*PROTECTED REGION END */
Std_ReturnType retValue = RTE_E_OK;
/* -------------------------------------- Data Read ----------------------------------------- */

/* -------------------------------------- Server Call Point -------------------------------- */

/* -------------------------------------- CDATA --------------------------------------------- */

/* -------------------------------------- Data Write ---------------------------------------- */

/* -------------------------------------- Trigger Interface --------------------------------- */

/* -------------------------------------- Mode Management ----------------------------------- */

/* -------------------------------------- Port Handling ------------------------------------- */

/* -------------------------------------- Exclusive Area ------------------------------------ */

/* -------------------------------------- Multiple Instantiation ---------------------------- */

/*PROTECTED REGION ID(User Logic :RE_OperaReq0_func) ENABLED START */
/* Start of user code - Do not remove this comment */
/* End of user code - Do not remove this comment */
/*PROTECTED REGION END */

}

在需求里我们需要这个runnable 来作为client server 的服务端。即前面client的代码,进行了event的写入。RTE 生成代码

         for (;;) {
           rtn = Rte_ReadQueue(&Rte_Queue_CPT_OperEvent_SWC_PP_CS_Interface_Oper_RequestOpt0.cmn, &srvQEl);
           if ( ( ((VAR(Std_ReturnType, AUTOMATIC))RTE_E_OK) == rtn ) || ( ((VAR(Std_ReturnType, AUTOMATIC))RTE_E_LOST_DATA) == rtn ) )
          {

              RE_OperaReq0_func(srvQEl.Opt0_Req);

              Rte_Var_CPT_OperEvent_Input_SWC_RPortPrototype_0_RequestOpt0_outstanding = FALSE;
              Rte_WriteQueue(srvQEl.clientQueue, &cliQEl);
          }
           else
          {
              break;
          }
        }

可以看出这里有个for(::) 内部一直在判断 client 端是否有调用(写入)

3.2.1.4 RE_OperaReq1_func

同上

4. 集成编译

暂无

5. 测试

暂无

原文始发于微信公众号(汽车与基础软件):Autosar ClientServer/ SenderReceiver实践

版权声明:admin 发表于 2023年11月2日 下午1:52。
转载请注明:Autosar ClientServer/ SenderReceiver实践 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...