【AUTOSAR COM 3.信号的收发流程TX/RX】

在这里插入图片描述
本系列文章的主题是CAN通讯,即属于通讯功能,对该功能再按模块细分,如下图3所示。其中CAN通讯的核心模块有4个:COM模块,PDU Router模块, CAN Interface模块和CAN Driver模块

从整个Com通信结构上看我们可以发现:

对于CAN Driver来说,与上层模块通讯的唯一接口就是CAN接口模块,通过这个模块可实现我们熟知的3个ECU通讯功能:

CAN通讯,通过接口层到PDU Router模块;(路径:CanDrv–CanIf–PduR–Com)
UDS服务,通过接口层到CANTp模块;(路径:CanDrv–CanIf–CanTp–PduR–Dcm)
XCP服务,通过接口层到XCP模块。(路径:CanDrv–CanIf–XCP)

1.Can的接收

回顾之前文章 menghuyouyou:根据ISO 11898-1标准可知, CAN接收功能需要使用通知(Indication)服务,那么怎么基于AUTOSAR架构实现呢?总的来说,AUTOSAR架构的CAN接收的软件实现流程图如下图4所示:
在这里插入图片描述
BSW调度器周期性调用CAN Driver模块的Can_MainFunction_Read函数;

CAN Driver模块的Can_MainFunction_Read函数将访问CanController(硬件)的寄存器,如前面文章所述的仲裁寄存器,数据寄存器和数据长度寄存器,并读取这些寄存器的数据

数据读取结束后,这时继续调用CAN Interface模块的CanIf_RxIndication函数,这样数据从CAN Driver模块传给了上一层的CAN Interface模块;

CAN Interface模块再调用PduR模块的PduR_RxIndication函数,将数据传到PduR模块;

PduR模块路由到Com模块,调用Com_RxIndication函数,将数据传到Com模块,Com模块将会把数据存入其缓存,供应用层软件读取使用。

另外再根据ISO 11898-1标准说明本文及之后内容,如下图5的红线之上部分。上述的4个核心模块,除了CAN Driver能够访问或配置硬件,其他模块均不能。它们之间将通过数据协议单元(PDU)形式实现数据传输,这些内容后面文章会进行详细介绍。

在这里插入图片描述

2.Can的发送

CAN发送功能需使用请求(Request)服务和确认(Comfirmation)服务,AUTOSAR架构的CAN发送功能如下图6、7所示。

在这里插入图片描述
BSW调度器周期性调用Com模块的Com_MainFunction_Tx函数,Com模块将从其缓存器中读取需发送的数据;

Com模块的Com_MainFunction_Tx函数将调用PduR模块的PduR_ComTransmit函数,将数据传给PduR模块;

PduR模块路由到CAN Interface模块,调用CanIf_Transmit函数,这样数据从PduR模块传给了下层的CAN Interface模块;

CAN Interface模块再调用Can Driver模块的Can_Write函数,将数据写入相应的寄存器;

与CAN接收功能一样,Can_Write函数将访问仲裁,数据长度和数据寄存器,将数据写入。

图7描述了数据发送后的确认过程,即:

BSW调度器周期性调用CAN Driver模块的Can_MainFunction_Write函数;

CAN Driver模块的Can_MainFunction_Write函数将访问CanController(硬件)有关寄存器,读取有关数据供向上层确认;

数据读取结束后,这时继续调用CAN Interface模块的CanIf_TxComfirmation函数,这样数据从CAN Driver模块传给了上层的CAN Interface模块;

CAN Interface模块再调用PduR模块的PduR_TxConfirmation函数,将数据传到PduR模块;

PduR模块路由到Com模块,调用Com_TxConfirmation函数,确认发送状态。

在这里插入图片描述

<think>嗯,我现在需要帮用户分析他提供的CAPL代码有什么问题。让我仔细看一下代码的结构和内容。 首先,用户定义了一个变量块,里面有word类型的ecu_tx、ecu_rx和ecu_fun_tx,分别赋值了十六进制的值。看起来这部分没问题,CAPL是支持十六进制字面量的,使用0x开头是正确的。 接下来是结构体struct Node_Info,包含word node_id、byte test_flag、word cycle_node、word nodeLostTime,还有一个byte数组msg_data[8]。结构体的定义看起来没问题,各成员的数据类型也是CAPL支持的,比如word是16位无符号整数,byte是8位。 然后声明了allPoints数组,类型是Node_Info,大小为20。这里可能有个问题,CAPL中数组声明是否需要指定大小?或者是否应该动态初始化?不过语法上struct Node_Info allPoints[20];应该是正确的,声明一个包含20个元素的数组。 接下来是allPoints[0]的初始化,使用了大括号括起的值。这里需要注意CAPL的结构体初始化语法是否正确。在C语言中,结构体初始化可以用这种形式,但CAPL可能有所不同。例如,是否需要在赋值时加上struct关键字,或者是否允许直接使用大括号初始化。可能的问题在于,CAPL中结构体初始化可能需要使用具体的构造函数或者逐个成员赋值,特别是在全局作用域中直接赋值可能不被允许。比如,在CAPL的全局变量区域,可能不允许执行这样的赋值操作,而只能在某个函数或on start块中进行。 另外,检查一下各个成员的赋值是否正确。node_id是0x285,这在word类型范围内(0到0xFFFF),没问题。test_flag是1,byte类型可以容纳。cycle_node和nodeLostTime分别是100和1000,word类型足够存储。msg_data数组初始化为全0,语法上正确。 另一个可能的错误是,CAPL中的数组初始化是否需要在声明时进行,或者在全局作用域中是否允许这种赋值语句。例如,在全局变量定义区域,通常只能进行声明和初始化,而不能有执行语句。所以allPoints[0] = {...};这行可能在全局作用域中是不允许的,应该放在on start或其他事件处理函数中。 还有,检查是否有遗漏的分号。结构体定义后应该有分号,用户代码中struct Node_Info后面有分号,没问题。数组声明后的分号也有。 总结可能的问题点: 1. 结构体初始化在全局作用域中的赋值是否正确,CAPL可能不允许在全局执行这样的赋值语句,只能在函数内部。 2. 结构体初始化语法是否正确,是否需要使用不同的格式,比如每个成员显式命名或使用构造函数。 3. 其他语法问题,比如逗号分隔、数据类型是否匹配等。 比如,在CAPL中,全局变量的初始化可能需要在声明时进行,而不能在后续单独赋值。所以正确的做法可能是在声明allPoints数组时直接初始化第一个元素,或者在on start块中赋值。 例如,修改为: struct Node_Info allPoints[20] = {{0x285, 1, 100, 1000, {0}}}; 或者在on start里写: on start { allPoints[0].node_id = 0x285; allPoints[0].test_flag = 1; // 其他成员赋值 } 或者使用数组初始化的方式,但可能在CAPL中不允许在全局作用域执行这样的赋值操作。 所以,用户代码的主要问题可能是在全局作用域中对allPoints[0]进行赋值,这在CAPL中是不允许的,必须将赋值操作放在事件处理函数中,如on start。</think>以下是对您提供的CAPL代码问题的分析及解决方案: $\textbf{主要问题}$: 1. $\textbf{全局作用域赋值错误}$ - 代码中 $\texttt{allPoints[0] = { ... };}$ 在$\textbf{全局作用域}$直接赋值,这在CAPL语法中$\color{red}{不被允许}$。此类操作必须放在$\textbf{事件处理函数}$中(如 $\texttt{on start}$) 2. $\textbf{结构体初始化语法不规范}$ - CAPL要求结构体初始化需使用$\texttt{.{}}$成员操作符或构造函数形式,不能直接使用C风格的$\texttt{{}}$初始化 $\textbf{详细解决方案}$: $$\begin{aligned} &\text{修改建议(两种方式)}:\\ &\boxed{1. \textbf{在on start中赋值}} \\ &\ \ \texttt{on start} \\ &\ \ \{\\ &\ \ \ \ allPoints[0].node\_id = 0x285; \\ &\ \ \ \ allPoints[0].test\_flag = 1; \\ &\ \ \ \ allPoints[0].cycle\_node = 100; \\ &\ \ \ \ allPoints[0].nodeLostTime = 1000; \\ &\ \ \ \ \@sys\_byteArrayCopy(allPoints[0].msg\_data, {0,0,0,0,0,0,0,0}); \\ &\ \ \}\\ &\\ &\boxed{2. \textbf{声明时初始化}} \\ &\ \ struct Node\_Info allPoints[20] = \{ \\ &\ \ \ \ \{0x285,1,100,1000,\{0,0,0,0,0,0,0,0\}\} \\ &\ \ \}; \\ \end{aligned}$$ $\textbf{其他注意事项}$: 1. $\texttt{msg\_data}$ 数组建议使用$\texttt{\@sys\_byteArrayInit}$或$\texttt{\@sys\_byteArrayCopy}$进行初始化 2. 十六进制常量$\texttt{0x285}$在word类型范围内(0-0xFFFF),无需修改 3. 数组索引$\texttt{[20]}$声明正确,但注意CAPL数组是$\textbf{静态分配}$,不支持动态扩展 $\textbf{正确代码示例}$: ```capl variables { word ecu_tx = 0x705, ecu_rx = 0x785, ecu_fun_tx = 0x7DF; struct Node_Info { word node_id; byte test_flag; word cycle_node; word nodeLostTime; byte msg_data[8]; }; struct Node_Info allPoints[20]; } on start { allPoints[0].node_id = 0x285; allPoints[0].test_flag = 1; allPoints[0].cycle_node = 100; allPoints[0].nodeLostTime = 1000; @sys_byteArrayInit(allPoints[0].msg_data, 0); // 初始化全0 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值