- 一、CoE FSM (ec_fsm_coe) — CoE SDO 传输状态机
- 概览
- 什么是 CoE FSM
- CoE FSM 状态机全图
- 技术详情
- 字典读取状态
- SDO 下载 (Download) 状态
- SDO 上传 (Upload) 状态
- SDO 分段传输时序
- 超时参数
- 常见 SDO 中止码
- 深入源码
- ec_fsm_coe 结构体
- 关键函数
- ec_fsm_coe_dictionary()
- ec_fsm_coe_transfer()
- 分段传输 (Segmented Transfer)
- 源文件索引
- 概览
- 二、EoE FSM (ec_fsm_eoe) — EoE IP 参数设置状态机
- 概览
- 什么是 EoE FSM
- EoE FSM 状态机全图
- 技术详情
- 状态详解
- EoE INIT_REQ 报文格式
- 响应超时
- EoE 数据收发流程图
- 深入源码
- ec_fsm_eoe 结构体
- ec_eoe_request 结构体
- 源文件索引
- 概览
- 三、FoE FSM (ec_fsm_foe) — FoE 文件传输状态机
- 概览
- 什么是 FoE FSM
- FoE FSM 状态机全图
- 技术详情
- 状态详解
- FoE OpCodes
- FoE 报文格式
- 固件升级端到端流程图
- 超时参数
- 深入源码
- ec_fsm_foe 结构体
- 关键实现细节
- 源文件索引
- 概览
- 四、SoE FSM (ec_fsm_soe) — SoE IDN 访问状态机
- 概览
- 什么是 SoE FSM
- SoE FSM 状态机全图
- 技术详情
- 状态详解
- SoE OpCode
- SoE 报文格式
- SoE 读写时序
- 超时参数
- 深入源码
- ec_fsm_soe 结构体
- 分片传输机制
- 源文件索引
- 概览
- 五、SII FSM (ec_fsm_sii) — SII/EEPROM 读写状态机
- 概览
- 什么是 SII FSM
- SII FSM 状态机全图
- 技术详情
- 状态详解
- EEPROM 读写操作时序
- 超时与等待参数
- 0x0502 寄存器位域
- 深入源码
- ec_fsm_sii 结构体
- 关键函数
- ec_fsm_sii_read()
- ec_fsm_sii_write()
- read_fetch 状态检查逻辑
- 源文件索引
- 概览
一、CoE FSM (ec_fsm_coe) — CoE SDO 传输状态机
3.4.4.6 — 通过 CoE (CANopen over EtherCAT) 协议进行 SDO 字典读取、SDO 上传和下载
概览
什么是 CoE FSM
CoE FSM 实现 CANopen over EtherCAT (CoE) 协议的状态机。它包含 3 个独立子功能:
- SDO 字典读取:读取从站的完整 SDO 字典(对象列表 → 对象描述 → 入口描述),13 个状态
- SDO 下载 (Download):向从站写入 SDO 数据(支持分段传输),8 个状态
- SDO 上传 (Upload):从从站读取 SDO 数据(支持分段传输),8 个状态
CoE 使用邮箱通信,协议类型 EC_MBOX_TYPE_COE (0x03)。
CoE FSM 状态机全图
技术详情
字典读取状态
| 状态 | 函数名 | 职责 |
|---|---|---|
| dict_start | ec_fsm_coe_dict_start |
检查 CoE 支持,发送 Get OD List 请求 |
| dict_request | ec_fsm_coe_dict_request |
等待 OD List 请求发送确认 |
| dict_check | ec_fsm_coe_dict_check |
轮询检查邮箱是否有响应 |
| dict_response | ec_fsm_coe_dict_response |
读取邮箱 OD List 响应 |
| dict_response_data | ec_fsm_coe_dict_response_data |
解析对象列表,创建 SDO 对象 |
| dict_desc_request | ec_fsm_coe_dict_desc_request |
发送 Get OD 请求获取对象描述 |
| dict_desc_check | ec_fsm_coe_dict_desc_check |
轮询检查邮箱 |
| dict_desc_response | ec_fsm_coe_dict_desc_response |
读取对象描述响应 |
| dict_desc_response_data | ec_fsm_coe_dict_desc_response_data |
解析对象名称和类型 |
| dict_entry_request | ec_fsm_coe_dict_entry_request |
发送 Get ED 请求获取入口描述 |
| dict_entry_check | ec_fsm_coe_dict_entry_check |
轮询检查邮箱 |
| dict_entry_response | ec_fsm_coe_dict_entry_response |
读取入口描述响应 |
| dict_entry_response_data | ec_fsm_coe_dict_entry_response_data |
解析入口名称和数据类型 |
SDO 下载 (Download) 状态
| 状态 | 函数名 | 职责 |
|---|---|---|
| down_start | ec_fsm_coe_down_start |
准备 SDO Download 请求 |
| down_request | ec_fsm_coe_down_request |
发送 SDO Download 请求到邮箱 |
| down_check | ec_fsm_coe_down_check |
轮询检查邮箱响应 |
| down_response | ec_fsm_coe_down_response |
读取 SDO Download 响应 |
| down_response_data | ec_fsm_coe_down_response_data |
判断是否需要分段传输 |
| down_seg_check | ec_fsm_coe_down_seg_check |
分段传输:检查邮箱 |
| down_seg_response | ec_fsm_coe_down_seg_response |
分段传输:读取段响应 |
| down_seg_response_data | ec_fsm_coe_down_seg_response_data |
分段传输:继续或完成 |
SDO 上传 (Upload) 状态
| 状态 | 函数名 | 职责 |
|---|---|---|
| up_start | ec_fsm_coe_up_start |
准备 SDO Upload 请求 |
| up_request | ec_fsm_coe_up_request |
发送 SDO Upload 请求到邮箱 |
| up_check | ec_fsm_coe_up_check |
轮询检查邮箱响应 |
| up_response | ec_fsm_coe_up_response |
读取 SDO Upload 响应 |
| up_response_data | ec_fsm_coe_up_response_data |
判断是否需要分段接收 |
| up_seg_request | ec_fsm_coe_up_seg_request |
分段传输:发送段请求 |
| up_seg_check | ec_fsm_coe_up_seg_check |
分段传输:检查邮箱 |
| up_seg_response | ec_fsm_coe_up_seg_response |
分段传输:读取段响应 |
| up_seg_response_data | ec_fsm_coe_up_seg_response_data |
分段传输:继续或完成 |
SDO 分段传输时序
超时参数
EC_FSM_COE_DICT_TIMEOUT = 1000 ms
常见 SDO 中止码
| 中止码 | 含义 |
|---|---|
| 0x05030000 | Toggle bit 未改变 |
| 0x05040000 | SDO 协议超时 |
| 0x06010000 | 不支持的对象访问 |
| 0x06010001 | 尝试读取只写对象 |
| 0x06010002 | 尝试写入只读对象 |
| 0x06020000 | 对象不存在 |
| 0x06040041 | 对象不能映射到 PDO |
| 0x06060000 | 访问失败(硬件错误) |
| 0x06070010 | 数据类型不匹配 |
| 0x06090011 | 子索引不存在 |
| 0x06090030 | 参数值超出范围 |
| 0x08000000 | 一般错误 |
| 0x08000020 | 数据无法传输或存储 |
| 0x08000021 | 数据无法传输或存储(本地控制) |
深入源码
ec_fsm_coe 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
slave |
ec_slave_t * |
目标从站 |
datagram |
ec_datagram_t * |
使用的 datagram |
state |
void (*)(ec_fsm_coe_t *, ec_datagram_t *) |
当前状态函数指针 |
request |
ec_sdo_request_t * |
当前 SDO 请求(上传/下载) |
jiffies_start |
unsigned long |
操作起始时间 |
toggle |
uint8_t |
分段传输的 toggle 位 |
sdos |
struct list_head |
临时 SDO 列表(字典读取) |
entry_count |
unsigned int |
字典入口计数 |
关键函数
ec_fsm_coe_dictionary()
启动 SDO 字典读取流程。获取对象列表 → 逐个获取对象描述 → 逐个获取入口描述。结果存储在 slave->sdo_dictionary 中。
ec_fsm_coe_transfer()
根据请求方向启动 SDO 上传或下载。使用 ec_sdo_request_t 结构体传递 Index、SubIndex 和数据。
分段传输 (Segmented Transfer)
当 SDO 数据超过邮箱大小时,使用分段传输:
- 下载路径:首包使用 SDO Download Req,后续使用 SDO Download Segment Req
- 上传路径:首包使用 SDO Upload Req,后续使用 SDO Upload Segment Req
- Toggle 位:每个段交替设置 toggle 位 (0/1),用于检测丢失
- 最小段数据大小:
EC_COE_DOWN_SEG_MIN_DATA_SIZE= 7 字节
源文件索引
| 文件 | 说明 |
|---|---|
master/fsm_coe.h |
CoE FSM 结构体和接口声明 |
master/fsm_coe.c |
CoE FSM 状态实现 (~2600 行,最大的 FSM 文件) |
master/fsm_slave.c |
调用方:sdo_request 和 dict_request 状态 |
master/fsm_slave_config.c |
调用方:sdo_conf 状态 |
二、EoE FSM (ec_fsm_eoe) — EoE IP 参数设置状态机
3.4.4.7 — 通过 EoE (Ethernet over EtherCAT) 设置从站 IP 参数
概览
什么是 EoE FSM
EoE FSM 负责通过 EtherCAT 邮箱协议向从站发送 EoE (Ethernet over EtherCAT) IP 参数设置请求。它可以配置从站网络接口的 MAC 地址、IP 地址、子网掩码、网关、DNS 服务器和主机名。
EoE FSM 仅处理 IP 参数设置(EC_EOE_TYPE_INIT_REQ/RES)。实际的 EoE 数据帧收发由 master/ethernet.c 中的 EoE 处理线程负责。
EoE FSM 状态机全图
技术详情
状态详解
| 状态 | 函数名 | 职责 |
|---|---|---|
| set_ip_start | ec_fsm_eoe_set_ip_start |
检查 EoE 支持,组装并发送 INIT_REQ 邮箱报文 |
| set_ip_request | ec_fsm_eoe_set_ip_request |
等待发送确认,WKC=0 时重发 |
| set_ip_check | ec_fsm_eoe_set_ip_check |
轮询检查从站邮箱是否有响应数据 |
| set_ip_response | ec_fsm_eoe_set_ip_response |
读取邮箱响应数据 |
| set_ip_response_data | ec_fsm_eoe_set_ip_response_data |
解析响应:验证类型和结果码 |
| end | ec_fsm_eoe_end |
设置成功 |
| error | ec_fsm_eoe_error |
设置失败 |
EoE INIT_REQ 报文格式
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Type | EC_EOE_TYPE_INIT_REQ (0x01) |
| 1 | 1 | — | 未使用 (0x00) |
| 2~3 | 2 | — | 未使用 (0x0000) |
| 4~7 | 4 | Flags | bit0=MAC, bit1=IP, bit2=子网掩码, bit3=网关, bit4=DNS, bit5=主机名 |
| 8~13 | 6 | MAC Address | 可选,由 Flags.bit0 控制 |
| 14~17 | 4 | IP Address | 可选,网络字节序 |
| 18~21 | 4 | Subnet Mask | 可选,网络字节序 |
| 22~25 | 4 | Default Gateway | 可选,网络字节序 |
| 26~29 | 4 | DNS Server | 可选,网络字节序 |
| 30~61 | 32 | DNS Name | 可选,主机名 |
响应超时
EC_EOE_RESPONSE_TIMEOUT = 3000 ms。发送 INIT_REQ 后,如果在 3 秒内未收到 INIT_RES 响应,则超时失败。
EoE 数据收发流程图
深入源码
ec_fsm_eoe 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
slave |
ec_slave_t * |
目标从站 |
retries |
unsigned int |
Datagram 重试计数 |
state |
void (*)(ec_fsm_eoe_t *, ec_datagram_t *) |
当前状态函数指针 |
datagram |
ec_datagram_t * |
使用的 datagram |
jiffies_start |
unsigned long |
请求起始时间 |
request |
ec_eoe_request_t * |
当前处理的 EoE 请求 |
ec_eoe_request 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
mac_address_included |
uint8_t |
是否包含 MAC 地址 |
ip_address_included |
uint8_t |
是否包含 IP 地址 |
subnet_mask_included |
uint8_t |
是否包含子网掩码 |
gateway_included |
uint8_t |
是否包含网关 |
dns_included |
uint8_t |
是否包含 DNS 服务器 |
name_included |
uint8_t |
是否包含主机名 |
mac_address |
uint8_t[6] |
MAC 地址 |
ip_address |
uint32_t |
IP 地址(主机字节序) |
subnet_mask |
uint32_t |
子网掩码 |
gateway |
uint32_t |
默认网关 |
dns |
uint32_t |
DNS 服务器 |
name |
char[EC_MAX_HOSTNAME_SIZE] |
主机名 |
result |
uint16_t |
从站返回的结果码 (0=成功) |
源文件索引
| 文件 | 说明 |
|---|---|
master/fsm_eoe.h |
EoE FSM 结构体和接口声明 |
master/fsm_eoe.c |
EoE FSM 状态实现 (~530 行) |
master/fsm_slave.c |
调用方:eoe_request 状态 |
master/ethernet.c |
EoE 处理线程(数据帧收发,非本 FSM) |
三、FoE FSM (ec_fsm_foe) — FoE 文件传输状态机
3.4.4.8 — 通过 FoE (File Access over EtherCAT) 协议进行固件升级和文件传输
概览
什么是 FoE FSM
FoE FSM 实现 EtherCAT FoE (File Access over EtherCAT) 协议,用于在主站和从站之间传输文件数据。主要用途是从站固件升级。
支持两种传输方向:
- 写入 (WRITE):主站向从站发送文件数据(固件升级)
- 读取 (READ):主站从从站读取文件数据
FoE 使用邮箱通信,数据按块分片传输,每块最大不超过邮箱大小。
FoE FSM 状态机全图
技术详情
状态详解
| 状态 | 函数名 | 职责 | 方向 |
|---|---|---|---|
| write_start | ec_fsm_foe_state_write_start |
准备并发送 WRQ (Write Request) | WRITE |
| wrq_sent | ec_fsm_foe_state_wrq_sent |
等待 WRQ 的 ACK 响应 | WRITE |
| data_sent | ec_fsm_foe_state_data_sent |
发送 DATA 块后等待 ACK | WRITE |
| ack_check | ec_fsm_foe_state_ack_check |
检查邮箱中是否有 ACK | WRITE |
| ack_read | ec_fsm_foe_state_ack_read |
读取 ACK 邮箱数据 | WRITE |
| ack_read_data | ec_fsm_foe_state_ack_read_data |
解析 ACK,决定继续发送或完成 | WRITE |
| read_start | ec_fsm_foe_state_read_start |
准备并发送 RRQ (Read Request) | READ |
| rrq_sent | ec_fsm_foe_state_rrq_sent |
等待 RRQ 的 DATA 响应 | READ |
| data_check | ec_fsm_foe_state_data_check |
检查邮箱中是否有 DATA | READ |
| data_read | ec_fsm_foe_state_data_read |
读取 DATA 邮箱数据 | READ |
| data_read_data | ec_fsm_foe_state_data_read_data |
解析 DATA,决定继续接收或完成 | READ |
| sent_ack | ec_fsm_foe_state_sent_ack |
发送 ACK 确认收到 DATA | READ |
| end | ec_fsm_foe_end |
传输成功完成 | — |
| error | ec_fsm_foe_error |
传输失败 | — |
FoE OpCodes
| OpCode | 值 | 说明 | 方向 |
|---|---|---|---|
| RRQ | 1 | 读请求 (Read Request) | 主站 → 从站 |
| WRQ | 2 | 写请求 (Write Request) | 主站 → 从站 |
| DATA | 3 | 数据帧 | 双向 |
| ACK | 4 | 确认帧 | 双向 |
| ERR | 5 | 错误帧 | 从站 → 主站 |
| BUSY | 6 | 忙帧 | 从站 → 主站 |
FoE 报文格式
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | OpCode | 操作码 (RRQ/WRQ/DATA/ACK/ERR/BUSY) |
| 1 | 1 | Reserved | 保留 |
| 2~5 | 4 | PacketNo / Password / ErrorCode | 取决于 OpCode |
| 6+ | 可变 | Data | RRQ/WRQ: 文件名+\0+密码; DATA: 文件数据 |
固件升级端到端流程图
超时参数
EC_FSM_FOE_TIMEOUT_JIFFIES = 3 * HZ (3 秒)
深入源码
ec_fsm_foe 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
slave |
ec_slave_t * |
目标从站 |
datagram |
ec_datagram_t * |
使用的 datagram |
state |
void (*)(ec_fsm_foe_t *, ec_datagram_t *) |
当前状态函数指针 |
request |
ec_foe_request_t * |
当前 FoE 请求 |
packet_no |
uint32_t |
当前包序号 |
previous_packet_no |
uint32_t |
上一个包序号(用于 ACK 验证) |
foe_data_size |
size_t |
当前 DATA 块大小 |
tx_errors |
uint32_t |
发送错误计数 |
rx_errors |
uint32_t |
接收错误计数 |
jiffies_start |
unsigned long |
操作起始时间 |
关键实现细节
FoE 实现要点
数据分片: 数据按邮箱大小分块传输,每块最大不超过 TX 邮箱大小
PacketNo 验证: ACK 中的 PacketNo 必须与发送的 DATA PacketNo 匹配
错误处理: 收到 ERR OpCode 时读取错误码,BUSY 时继续等待
重试机制: tx_errors/rx_errors 计数,Datagram 级别有 retries
FoE Header: 固定 6 字节 (OpCode + Reserved + 4字节 PacketNo/Password/ErrorCode)
源文件索引
| 文件 | 说明 |
|---|---|
master/fsm_foe.h |
FoE FSM 结构体和接口声明 |
master/fsm_foe.c |
FoE FSM 状态实现 (~1100 行) |
master/fsm_slave.c |
调用方:foe_request 状态 |
tool/CommandFoeWrite.cpp |
用户空间发起 FoE 写入 |
tool/CommandFoeRead.cpp |
用户空间发起 FoE 读取 |
四、SoE FSM (ec_fsm_soe) — SoE IDN 访问状态机
3.4.4.9 — 通过 SoE (SERCOS over EtherCAT) 协议读写伺服驱动 IDN 参数
概览
什么是 SoE FSM
SoE FSM 实现 SERCOS over EtherCAT (SoE) 协议的状态机,用于读写伺服驱动的 IDN (Identification Number) 参数。SoE 协议将 SERCOS 的服务通道映射到 EtherCAT 邮箱通信。
支持两种操作:
- IDN 读取 (Read):读取伺服驱动参数(位置、速度、扭矩等)
- IDN 写入 (Write):写入伺服驱动配置参数
SoE FSM 状态机全图
技术详情
状态详解
| 状态 | 函数名 | 职责 | 方向 |
|---|---|---|---|
| read_start | ec_fsm_soe_read_start |
准备 SoE 读请求 | READ |
| read_request | ec_fsm_soe_read_request |
发送读请求到邮箱,等待响应 | READ |
| read_check | ec_fsm_soe_read_check |
轮询检查邮箱是否有响应 | READ |
| read_response | ec_fsm_soe_read_response |
读取邮箱响应数据 | READ |
| read_response_data | ec_fsm_soe_read_response_data |
解析 SoE 响应,处理分片 | READ |
| write_start | ec_fsm_soe_write_start |
准备 SoE 写请求 | WRITE |
| write_request | ec_fsm_soe_write_request |
发送写请求到邮箱,等待响应 | WRITE |
| write_check | ec_fsm_soe_write_check |
轮询检查邮箱是否有响应 | WRITE |
| write_response | ec_fsm_soe_write_response |
读取邮箱响应数据 | WRITE |
| write_response_data | ec_fsm_soe_write_response_data |
解析 SoE 响应,处理分片 | WRITE |
| end | ec_fsm_soe_end |
操作成功完成 | — |
| error | ec_fsm_soe_error |
操作失败 | — |
SoE OpCode
| OpCode | 值 | 说明 |
|---|---|---|
| Read Request | 0x01 | IDN 读取请求 |
| Read Response | 0x02 | IDN 读取响应 |
| Write Request | 0x03 | IDN 写入请求 |
| Write Response | 0x04 | IDN 写入响应 |
SoE 报文格式
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 (邮箱头) | 6 | MBox Header | 邮箱协议头 (Type=EC_MBOX_TYPE_SOE) |
| 6 | 1 | OpCode | 操作码 (0x01~0x04) |
| 7 | 1 | Incomplete | bit0= fragmented (分片标志) |
| 8~9 | 2 | IDN / Elements | IDN 号 (低 15 位) + 数据集选择 (高 1 位) |
| 10+ | 可变 | Data | 请求/响应数据 |
SoE 读写时序
超时参数
EC_SOE_RESPONSE_TIMEOUT = 1000 ms
深入源码
ec_fsm_soe 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
slave |
ec_slave_t * |
目标从站 |
datagram |
ec_datagram_t * |
使用的 datagram |
state |
void (*)(ec_fsm_soe_t *, ec_datagram_t *) |
当前状态函数指针 |
request |
ec_soe_request_t * |
当前 SoE 请求 |
jiffies_start |
unsigned long |
操作起始时间 |
分片传输机制
当 IDN 数据超过邮箱大小时,SoE FSM 使用分片传输:
- 响应中的
Incomplete位 (bit0) 置位表示还有后续数据 - 主站在收到分片响应后自动发起下一次请求
- 写入路径:数据按邮箱大小分块逐片发送
- 读取路径:收到分片响应后自动请求下一片
源文件索引
| 文件 | 说明 |
|---|---|
master/fsm_soe.h |
SoE FSM 结构体和接口声明 |
master/fsm_soe.c |
SoE FSM 状态实现 (~800 行) |
master/fsm_slave.c |
调用方:soe_request 状态和 config_soe |
tool/CommandSoeRead.cpp |
用户空间 SoE 读取 |
tool/CommandSoeWrite.cpp |
用户空间 SoE 写入 |
五、SII FSM (ec_fsm_sii) — SII/EEPROM 读写状态机
3.4.4.10 — 从站 EEPROM (SII) 的读写访问状态机
概览
什么是 SII FSM
SII FSM(Slave Information Interface FSM)负责通过 ESC 的 EEPROM 访问寄存器读写从站的 SII (Slave Information Interface) 数据。每次操作读写 2 个字 (4 字节)。
SII FSM 被 Slave Scan FSM(读取从站信息)和 Master FSM(写入 EEPROM)调用。支持两种寻址模式:自动递增地址和配置站地址。
SII FSM 状态机全图
技术详情
状态详解
| 状态 | 函数名 | 职责 | ESC 寄存器 |
|---|---|---|---|
| start_reading | ec_fsm_sii_state_start_reading |
FPWR/APWR 写入读命令到 SII 寄存器 | 0x0502 (FPWR/APWR) |
| read_check | ec_fsm_sii_state_read_check |
验证写入成功,发起读取检查 | 0x0502 (FPRD/APRD) |
| read_fetch | ec_fsm_sii_state_read_fetch |
轮询等待 EEPROM 就绪,获取数据 | 0x0502 (FPRD/APRD) |
| start_writing | ec_fsm_sii_state_start_writing |
FPWR 写入写命令和数据到 SII 寄存器 | 0x0502 (FPWR) |
| write_check | ec_fsm_sii_state_write_check |
验证写入命令被接受 | 0x0502 (FPRD) |
| write_check2 | ec_fsm_sii_state_write_check2 |
轮询等待写入完成(检查忙/错误位) | 0x0502 (FPRD) |
| end | ec_fsm_sii_state_end |
操作成功完成 | — |
| error | ec_fsm_sii_state_error |
操作失败 | — |
EEPROM 读写操作时序
超时与等待参数
| 常量 | 值 | 说明 |
|---|---|---|
SII_LOAD_TIMEOUT |
500 ms | EEPROM 加载超时(首次读取时等待 EEPROM 完成加载) |
SII_TIMEOUT |
20 ms | 读/写操作超时 |
SII_INHIBIT |
5 ms | 写入后等待评估时间 |
0x0502 寄存器位域
| 字节偏移 | 读路径 | 写路径 |
|---|---|---|
| +0 | 地址配置: bit7=双字节地址, bit0=读写(0=read,1=write) | |
| +1 | bit5=错误, bit4=加载中, bit0=忙 | bit1=写忙 | 操作类型: 0x01=读, 0x02=写 |
| +2~+3 | 字偏移地址 (word offset) | |
| +4~+5 | 保留 (写路径: 0x0000) | |
| +6~+9 | 读取的数据 (4 字节) | 写入的数据 (2 字节) |
深入源码
ec_fsm_sii 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
slave |
ec_slave_t * |
目标从站 |
datagram |
ec_datagram_t * |
使用的 datagram |
state |
void (*)(ec_fsm_sii_t *, ec_datagram_t *) |
当前状态函数指针 |
word_offset |
uint16_t |
读写的字偏移 |
mode |
ec_fsm_sii_addressing_t |
寻址模式: INCREMENT / CONFIGURED |
value |
uint8_t[4] |
读取/写入的数据 (最多 4 字节) |
retries |
unsigned int |
Datagram 超时重试计数 |
jiffies_start |
unsigned long |
操作起始时间 |
check_once_more |
uint8_t |
超时后再检查一次的标志 |
eeprom_load_retry |
uint8_t |
EEPROM 加载重试标志 |
关键函数
ec_fsm_sii_read()
初始化读操作:设置 word_offset、mode,将状态设为 start_reading。
ec_fsm_sii_write()
初始化写操作:设置 word_offset、mode,复制 2 字节写入数据到 fsm->value,将状态设为 start_writing。
read_fetch 状态检查逻辑
检查 ESC 0x0502 寄存器的位域:
- bit5 (0x20) = 错误 → 进入 error
- bit4 (0x10) = EEPROM 加载中 → 继续等待 (≤500ms)
- bit0 (0x01) / bit7 (0x80) = 操作忙 → 继续等待 (≤20ms)
- bit6 (0x40) = 写入失败 → 进入 error
- 全部清零 → 数据就绪,从 +6 偏移复制 4 字节到
fsm->value
源文件索引
| 文件 | 说明 |
|---|---|
master/fsm_sii.h |
SII FSM 结构体和接口声明 |
master/fsm_sii.c |
SII FSM 状态实现 (~600 行) |
master/fsm_slave_scan.c |
调用方:扫描时读取 EEPROM |
master/fsm_master.c |
调用方:用户空间发起的 SII 写入 |
