AUTOSAR ETH模块(3)——接口功能分析
本文将按照我的理解,对以太网的数据发送流程进梳理,以求更容易理解整个模块、
先附上规范链接,建议组合学习:
https://www.autosar.org/fileadmin/standards/R18-10_R4.4.0_R1.5.0/CP/AUTOSAR_SWS_EthernetDriver.pdf
在研究接口的作用和类型之前,了解 ETH 的通信流程可以帮助我们理解接口的功能及其实现的操作。本章着重介绍与数据发送功能息息相关的接口。
目录
数据发送流程
接口分析
Eth_Init
函数原型
规范说明
Eth_SetControllerMode
函数原型
规范说明
Eth_GetControllerMode
函数原型
规范说明
Eth_GetPhysAddr
函数原型
规范说明
Eth_SetPhysAddr
函数原型
规范说明
Eth_UpdatePhysAddrFilter
函数原型
规范说明
Eth_WriteMii
函数原型
规范说明
Eth_ReadMii
函数原型
规范说明
Eth_ProvideTxBuffer
函数原型
规范说明
Eth_Transmit
函数原型
规范说明
Eth_Receive
函数原型
规范说明
Eth_TxConfirmation
函数原型
规范说明
数据发送流程
简单来讲,首先在完成 ETH 模块初始化完成之后,将 以太网控制器 和 PHY芯片 的模式设置为发送状态,然后将要发送的数据填入缓冲区,然后发送出去,最后调用回调函数来通知数据是否发送成功。
接口分析
Eth_Init
函数原型
void Eth_Init(
const Eth_ConfigType* CfgPtr
)
参数类型 | 参数名称 | 方向 | 说明 |
const Eth_ConfigType* | CfgPtr | 输入 | 指向包含所有初始化内容的结构体指针 |
返回值:无
顾名思义,该接口函数实现的功能就是以太网的初始化。
Eth_ConfigType是一个结构体,存储着需要初始化的内容。由于包含指向例如 控制器索引、PHY相关配置 等的指针,因此后续所有函数只有再调用该接口函数之后才能正常使用。所以该接口的入参为一个不可修改的结构体指针,并通过指针所指向的数据来实现以太网的初始化。
规范说明
上图为该接口的相关规范,以及对应翻译。大概主要意思是 介绍该接口对以太网控制器的操作、程序运行出现问题时产生的错误类型 和 该接口必须在初始化时执行 三点。
先说对控制器的操作,翻译过来的内容如下几点:
1. 禁用所有控制器
2. 清除等待的以太网中断
3. 配置所有控制器参数(如中断、帧长、过滤器等)
4. 配置所有发送/接收资源(例如缓冲区初始化)
5. 删除所有待处理的发送和接收请求
总结来说,就是清除所有待执行的任务和缓冲区,然后配置参数并关闭控制器。
下表是常见的开发错误,当我们开启 开发错误检测(Det)功能后,如果程序执行出现问题,一般会抛出以下几种错误,出现这些错误的原因也就这几种,后面再出现类似内容的话就不多赘述了。
错误类型 | 错误码 | Value |
Invalid controller index (无效的控制器索引) | ETH_E_INV_CTRL_IDX | 0x01 |
Eth module or controller was not initialized (模块或控制器未初始化) | ETH_E_UNINIT | 0x02 |
Invalid pointer in parameter list (参数列表中的指针无效) | ETH_E_PARAM_POINTER | 0x03 |
Invalid parameter (无效的参数) | ETH_E_INV_PARAM | 0x04 |
Invalid mode (无效的模式) | ETH_E_INV_MODE | 0x05 |
Eth_SetControllerMode
函数原型
Std_ReturnType Eth_SetControllerMode(
uint8 CtrlIdx,
Eth_ModeType CtrlMode
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
Eth_ModeType | CtrlMode | 输入 | 枚举类型,代表控制器的模式:ETH_MODE_DOWN 0x00 禁用控制器 ETH_MODE_ACTIVE 0x01 启用控制器 |
返回值:Std_ReturnType(enum)
E_OK: 模式设置成功
E_NOT_OK: 控制器模式修改失败
该接口实现对控制器模式的切换。根据 CtrlIdx 确定要操作的控制器,CtrlMode 为要设置的模式,根据这些参数来对控制器进行操作。返回值为枚举类型,当模式设置成功时返回 E_OK ,反之则为 E_NOT_OK 。
对于有返回值的函数,我们可以通过判断返回值来确定函数是否执行成功。
初始化完成之后,需要开启控制器才能进行数据的发送和接收;在某些场合下需要禁用以太网功能时,使用这个接口同样可以关闭控制器,以实现停止接收和发送以太网帧。
规范说明
这段的意思是开启或关闭控制器时,所进行的一系列操作。
当CtrlMode为 ETH_MODE_DOWN 时,禁用以太网控制器并重置所有发送和接收缓冲区;
当CtrlMode为 ETH_MODE_ACTIVE 时,则启用控制器和所有发送和接收缓冲区。
在上个接口也有提到开发错误检测功能,并附上相关返回值的内容,考虑到篇幅问题就不叙述了,自行分辨即可。从该接口开始,所有接口都需要先进行控制器初始化(Eth_Init)然后才能执行并生效。
Eth_GetControllerMode
函数原型
Std_ReturnType Eth_GetControllerMode(
uint8 CtrlIdx,
Eth_ModeType* CtrlModePtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
Eth_ModeType* | CtrlMode | 输出 | 枚举类型指针,存放当前控制器的模式:ETH_MODE_DOWN 0x00 禁用控制器 ETH_MODE_ACTIVE 0x01 启用控制器 |
返回值:Std_ReturnType(enum)
E_OK: 模式获取成功
E_NOT_OK: 控制器模式获取失败
此接口能够获取当前控制器的状态。索引到控制器之后,接口获取当前控制器的模式,并将模式状态存入指针 CtrlMode 所指向的内存。接口执行完成后,通过判断指针所指向的值就能知晓当前控制器的状态。
规范说明
此处规范只是介绍了接口功能和开发错误,不过多说明。
Eth_GetPhysAddr
函数原型
void Eth_GetPhysAddr(
uint8 CtrlIdx,
uint8* PhysAddrPtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
uint8* | PhysAddrPtr | 输出 | 按网络字节顺序的物理源地址 (MAC 地址)。 |
返回值:无
该接口负责实现获取MAC地址,指针负责存储获取到的地址。MAC地址简单来说和身份证号一样,每个人都是独一无二的。MAC就是自己的身份证号,也就是发送方;对应的接收方的地址就是DST地址。
规范说明
Eth_SetPhysAddr
函数原型
void Eth_SetPhysAddr(
uint8 CtrlIdx,
const uint8* PhysAddrPtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
const uint8* | PhysAddrPtr | 输入 | 按网络字节顺序存储物理源地址 (MAC 地址)。 |
返回值:无
索引控制器后,接口将原MAC地址修改为传入的地址。
规范说明
Eth_UpdatePhysAddrFilter
函数原型
Std_ReturnType Eth_UpdatePhysAddrFilter(
uint8 CtrlIdx,
const uint8* PhysAddrPtr,
Eth_FilterActionType Action
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
const uint8* | PhysAddrPtr | 输入 | 指向 要添加或删除的地址 的指针 |
Eth_FilterActionType | Action | 输入 |
枚举,表示要对地址指针执行的操作:ETH_ADD_TO_FILTER 0x00
将MAC地址添加到过滤器中,允许接收
ETH_REMOVE_FROM_FILTER 0x01
将MAC地址从过滤器中删除,拒绝接收
|
返回值:Std_ReturnType(enum)
E_OK: 过滤器成功配置
E_NOT_OK: 过滤器无法修改
该接口实现对过滤器的操作。当硬件无法实现过滤或者直接通过软件进行过滤时,可以使用此接口。只有存入过滤器的地址才能被接收。通过 Action 的值,结合 PhysAddrPtr 来实现MAC地址的添加或删除。
规范说明
规范中提到的回调函数 RxIndication() 是指 EthIf_RxIndication,此处含义为 如果地址匹配,则在接收时会 触发该回调函数;如果不匹配,那么该帧就会被丢弃,不会被接收。
在控制器上更新物理地址接收过滤器。通过添加或删除过滤器可以实现控制器想要接收的报文。如果将地址设置为FF:FF:FF: FF:FF:FF,则完全打开过滤器;如果设置为设置为00:00:00:00:00:00,则只会接收该地址的报文。
Eth_WriteMii
函数原型
Std_ReturnType Eth_WriteMii(
uint8 CtrlIdx,
uint8 TrcvIdx,
uint8 RegIdx,
uint16 RegVal
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
uint8 | TrcvIdx | 输入 | MII 收发器索引 |
uint8 | RegIdx | 输入 |
收发器寄存器索引
|
uint16 | RegVal | 输入 | 要写入收发器寄存器的值 |
返回值:Std_ReturnType(enum)
E_OK: 服务接受
E_NOT_OK: 服务被拒绝
通过 CtrlIdx 和 TrcvIdx 可以锁定要操作的 控制器 和 收发器(也就是PHY芯片),然后根据RegIdx 对收发器寄存器进行索引,将 RegVal 写入寄存器。
写收发寄存器,也就是配置PHY芯片的参数和工作模式等。本质上就是配置 PHY芯片。
规范说明
当MII访问完成时,将调用EthTrcv_WriteMiiIndication() 来通知上层数据写入完成。在预编译阶段可以通过修改EthCtrlEnableMii的开关来选择是否开启Mii功能。
Eth_ReadMii
函数原型
Std_ReturnType Eth_ReadMii(
uint8 CtrlIdx,
uint8 TrcvIdx,
uint8 RegIdx,
uint16* RegValPtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
uint8 | TrcvIdx | 输入 | MII 收发器索引 |
uint8 | RegIdx | 输入 |
收发器寄存器索引
|
uint16* | RegValPtr | 输出 | 存储收发器寄存器内容的指针 |
返回值:Std_ReturnType(enum)
E_OK: 服务接受
E_NOT_OK: 服务被拒绝
根据索引将收发器寄存器的值存入指针 RegValPtr,获取PHY芯片的参数和状态。
规范说明
当MII访问完成时,将调用 EthTrcv_ReadMiiIndication() 来通知上层数据写入完成。在预编译阶段可以通过修改 EthCtrlEnableMii 的开关来选择是否开启Mii功能。
Eth_ProvideTxBuffer
函数原型
BufReq_ReturnType Eth_ProvideTxBuffer(
uint8 CtrlIdx,
uint8 Priority,
Eth_BufIdxType* BufIdxPtr,
uint8** BufPtr,
uint16* LenBytePtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
uint8 | Priority | 输入 | 发送缓冲区 FIFO 选择的帧优先级 |
Eth_BufIdxType* | BufIdxPtr | 输出 | 发送缓冲区资源的索引 |
uint8** | BufPtr | 输出 |
指向发送缓冲区的指针
|
uint16* | LenBytePtr | 输入,输出 | 帧字节长度 输入:预期需要的字节长度 输出:实际使用的字节长度 |
返回值:BufReq_ReturnType(enum)
BUFREQ_OK: 成功
BUFREQ_E_NOT_OK: 检测到开发错误
BUFREQ_E_BUSY: 所有缓冲区都在使用
BUFREQ_E_OVFL: 请求的缓冲区过大
该接口实现对指定优先级的 FIFO 的缓冲区的操作。和CAN类似,以太网也存在类似的FIFO。当 FIFO 中同时存在多帧时,通过 Priority 来指定帧在发送时的优先级,BufIdxPtr 指向的缓冲区资源就是存放要发送的数据帧的内存空间,BufPtr 表示的就是数据帧的字节长度,表达的含义如上表所示,根据输入和输出情况的不同,其含义也不一样。
规范说明
对索引控制器的指定FIFIO缓冲区进行操作。通过该接口将数据存入缓冲区,并且驱动程序会锁定该缓冲区,直到被Eth_Transmit调用。
当 Eth_SetControllerMode 禁用以太网控制器之后,所有发送缓冲区都要被释放。
Eth_Transmit
函数原型
Std_ReturnType Eth_Transmit(
uint8 CtrlIdx,
Eth_BufIdxType BufIdx,
Eth_FrameType FrameType,
boolean TxConfirmation,
uint16 LenByte,
const uint8* PhysAddrPtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
Eth_BufIdxType | BufIdx | 输入 | 发送缓冲区资源索引 |
Eth_FrameType | FrameType | 输入 | 帧头类型 |
boolean | TxConfirmation | 输入 |
是否开启传输成功确认
|
uint16 | LenByte | 输入 | 缓冲区数据长度 |
const uint8* | PhysAddrPtr | 输入 | 目的MAC地址 |
返回值:Std_ReturnType(enum)
E_OK: 发送成功
E_NOT_OK: 发送失败
调用这个接口可以将缓冲区存放的数据帧发送出去。索引的要发送的缓冲区之后,会根据以太网帧的格式结合其他参数构建数据帧并发送。
需要注意的是,该接口的返回值并不是代表发送成功,而是检测到发送缓冲区的数据是否被释放,并不能代表数据被成功发出。如果开启了传出成功确认,在发送完成后会调用Eth_TxConfirmation 来通知上层是否发送成功。
规范说明
将缓冲区数据发送到指定的目标地址。在传输完成后,驱动程序应该释放缓冲区。际缓冲区释放的具体时间由实现决定,例如在 Eth_TxConfirmation、Eth_MainFunction 或下一次 Eth_ProvideTxBuffer 期间。
同样的,当控制器被 Eth_SetControllerMode 禁用后,也会释放所有缓冲区。
Eth_Receive
函数原型
void Eth_Receive(
uint8 CtrlIdx,
uint8 FifoIdx,
Eth_RxStatusType* RxStatusPtr
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
uint8 | FifoIdx | 输入 | FIFO 索引 |
Eth_RxStatusType* | RxStatusPtr | 输出 | 存放接收相关信息的结构体指针 |
返回值:无
该接口能够从 接收FIFO 中读取收到的数据帧,RxStatusPtr 用于指示是否已接收帧,如果状态为已接收,则指示相关 fifo 中是否有更多帧可用。
规范说明
接收指定缓冲区的帧。除了接收该接口还可以通过回调函数EthIf_RxIndication来提示缓冲区是否还有更多的帧。
Eth_TxConfirmation
函数原型
void Eth_TxConfirmation(
uint8 CtrlIdx
)
参数类型 | 参数名称 | 方向 | 说明 |
uint8 | CtrlIdx | 输入 | 控制器索引 |
返回值:无
当 Eth_Transmit 启用了传输确认之后,便会调用该接口检测数据帧是否发送成功。该函数通过调用回调函数 EthIf_TxConfirmation 来确认对应索引的以太网控制器的帧是否发送成功。
规范说明
检查所有已经填充数据的缓冲区是否发送成功。对应发送成功的帧,该接口调用回调函数EthIf_TxConfirmation为每个发出的帧进行传输确认。若之前通过调用 Eth_Transmit 函数启用了传输确认,则函数应释放缓冲区资源。
以太网软件驱动程序应调用 EthIf_TxConfirmation,并将 Result 设置为 E_OK 以指示传输成功;从 Interrupt 例程(在 Interrupt 模式下)或从 Polling 模式下的 Eth_TxConfirmation 例程(如果已启用通知)。
如果传输失败,以太网软件驱动程序应调用 EthIf_TxConfirmation,并将 Result 设置为 E_NOT_OK。
对 EthIf_TxConfirmation 的调用并将 Result 设置为 E_NOT_OK 应允许上层实现简单的锁定方案。它可以依赖于这样一个事实,即每次调用 Eth_Transmit 时,EthIf_TxConfirmation 都会在之后被调用。
以太网软件驱动程序应调用 EthIf_RxIndication 以指示从中断例程(在中断模式下)或从轮询模式下的Eth_Receive例程成功接收。