CanIf发送PDU机制实例代码分析

简介: CanIf发送PDU机制实例代码分析

1 发送PDU的前提条件

CanIf要让发送PDU传输到CAN驱动层去发送,必须满足下面三个条件:

  • (1)Ecum 初始化阶段应成功调用CanIf_Init ,Can_Init
  • (2)PDU模式处于 CANIF_GET_TX_ONLINE/ CANIF_GET_ONLINE
  • (3)控制器模式处于CANIF_CS_STARTED

上面的三个条件,有一个不满足,发送请求则不会得到执行,发送接口函数CanIf_Transmit返回 E_NOT_OK。

2 发送PDU提供的接口

上层通过调用接口CanIf_Transmit(< TxPduId>, < PduInfoPtr>)来请求发送。函数的具体实现如下:

Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId,
    const PduInfoType *PduInfoPtr)
    {
  Can_PduType canPdu;
  const CanIf_TxPduConfigType *txEntry;
  CanIf_ControllerModeType csMode;
  CanIf_ChannelGetModeType pduMode;
  VALIDATE(CanIf_Global.initRun, CANIF_TRANSMIT_ID, CANIF_E_UNINIT );
  VALIDATE((PduInfoPtr != 0), CANIF_TRANSMIT_ID, CANIF_E_PARAM_POINTER );
  // Get the controller from L-PDU handle
  txEntry = CanIf_FindTxPduEntry(CanTxPduId);
  if (txEntry == 0)
  {
    VALIDATE(FALSE, CANIF_TRANSMIT_ID, CANIF_E_INVALID_TXPDUID);
    return E_NOT_OK;
  }
  CanIf_Arc_ChannelIdType channel = txEntry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef;
  // Get and verify the controller mode
  if (CanIf_GetControllerMode(channel, &csMode) == E_NOT_OK){
    return E_NOT_OK;
  }
  if (csMode != CANIF_CS_STARTED){  // CANIF_161
    return E_NOT_OK;
  }
  // Get and verify the PDU channel mode control
  if (CanIf_GetPduMode(channel, &pduMode) == E_NOT_OK){
    return E_NOT_OK;
  }
  if ((pduMode != CANIF_GET_TX_ONLINE) && (pduMode != CANIF_GET_ONLINE)){
    return E_NOT_OK;
  }
  canPdu.id = txEntry->CanIfCanTxPduIdCanId;
  canPdu.length = PduInfoPtr->SduLength;
  canPdu.sdu = PduInfoPtr->SduDataPtr;
  canPdu.swPduHandle = CanTxPduId;
  Can_ReturnType rVal = Can_Write(txEntry->CanIfCanTxPduHthRef->CanIfHthIdSymRef, &canPdu);
  if (rVal == CAN_NOT_OK){
    return E_NOT_OK;
  }
  if (rVal == CAN_BUSY)  // CANIF 082, CANIF 161
  {
    // Tx buffering not supported so just return.
    return E_NOT_OK;
  }
  return E_OK;
}
static const CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)
#endif
{
 if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds) {
  return NULL;
 } else {
  return &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[id];
 }
}

通过< TxPduId>参数,查询配置结构 CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[TxPduId],即CanIfTxPduConfigData[[TxPduId];见如下代码:

3 成功发送PDU的行为。。。

相关文章
|
7月前
|
设计模式
策略模式在数据接收和发送场景的应用
策略模式在数据接收和发送场景的应用
|
网络协议 网络架构
数据从发出到接收的细节介绍{封装与解封装}
本文将介绍了详细的封装在每一层的具体的操作,可以让大家学习到数据从发出到收到的具体过程。
|
7月前
|
设计模式 监控 网络协议
socket通信处于网络协议那一层和两种接收发送消息方式
socket通信处于网络协议那一层和两种接收发送消息方式
102 2
|
数据库
SIP 协议消息应答代码解释详录
SIP 协议消息应答代码解释详录
|
7月前
Socket网络编程练习题二:客户端发送一条数据,接收服务端反馈的消息并打印;服务端接收数据并打印,再给客户端反馈消息
Socket网络编程练习题二:客户端发送一条数据,接收服务端反馈的消息并打印;服务端接收数据并打印,再给客户端反馈消息
|
7月前
Socket网络编程练习题一:客户端多次发送数据,服务端多次接收数据并打印
Socket网络编程练习题一:客户端多次发送数据,服务端多次接收数据并打印
|
NoSQL 数据建模 API
UCX-UCT统一通信传输层3-服务端和客户端调用栈详解(及相关)_源码解读
主流程(服务端或客户端): 1. 主函数中解析命令行参数(parse_cmd), 设置默认服务端口 2. 初始化上下文(ucs_async_context_create, 异步事件上下文用于管理定时器和FD通知), 在其中, 初始化多生产者/多消费者队列(ucs_mpmc_queue_init), 初始化非阻塞异步轮询器(ucs_async_poll_init), 初始化可重入自旋锁上下文等 3. 创建工人(uct_worker_create), 工人代表着 progress 的引擎。 可以在应用程序中创建多个进度引擎,例如供多个线程使用 4. 根据入参查找期望的传输层(dev_tl_loo
373 1
|
网络架构
7号信令中自环的原理和方法
自环顾名思义就是自己发自己收。物理上收发互连,逻辑上收发互连。这样使得MTP1,MTP2,MTP3层物理上,逻辑上都可以连通,自环就设置完成了。将交换上收发互连,让MPT1,MTP2连通,然后设置两个本端点码,对端点码分别是另一个本端点码,定义信令链路集,定义信令路由,定义SLC,这样就形成了自环,这样使得MTP3层连通。自环就设置完成。
7号信令中自环的原理和方法
|
存储 网络协议 数据处理
协议栈——收发数据(拼接网络包,自动重发,滑动窗口机制)
协议栈——收发数据(拼接网络包,自动重发,滑动窗口机制)
398 1
LINUX编程实战指发送UDP消息
LINUX编程实战指发送UDP消息